[llvm] 43ad521 - [lldb][AArch64] Add reading of TLS tpidr register from core files

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 3 05:06:15 PDT 2023


Author: David Spickett
Date: 2023-08-03T12:06:06Z
New Revision: 43ad521f2fa9a50e6b30425a3b9fb3025b42587a

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

LOG: [lldb][AArch64] Add reading of TLS tpidr register from core files

7e229217f4215b519b886e7881bae4da3742a7d2 did live processes, this does
core files. Pretty simple, there is an NT_ARM_TLS note that contains
at least tpidr, and on systems with the Scalable Matrix Extension (SME), tpidr2
as well.

tpidr2 will be handled in future patches for SME support.

This NT_ARM_TLS note has always been present but it seems convenient to
handle it as "optional" inside of LLDB. We'll probably want the flexibility
when supporting tpidr2.

Normally the C library would set tpidr but all our test sources build
without it. So I've updated the neon test program to write to tpidr
and regenerated the corefile.

I've removed the LLDB_PTRACE_NT_ARM_TLS that was unused, we get
what we need from llvm's defs instead.

Reviewed By: omjavaid

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

Added: 
    

Modified: 
    lldb/include/lldb/Host/linux/Ptrace.h
    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-neon.c
    lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core
    llvm/docs/ReleaseNotes.rst

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Host/linux/Ptrace.h b/lldb/include/lldb/Host/linux/Ptrace.h
index 29489d1ae4862f..aabd3fd4fc5573 100644
--- a/lldb/include/lldb/Host/linux/Ptrace.h
+++ b/lldb/include/lldb/Host/linux/Ptrace.h
@@ -57,6 +57,4 @@ typedef int __ptrace_request;
 #define PTRACE_POKEMTETAGS 34
 #endif
 
-#define LLDB_PTRACE_NT_ARM_TLS 0x401 // ARM TLS register
-
 #endif // liblldb_Host_linux_Ptrace_h_

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 676e450c4846ad..d306c818e89f4a 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -47,6 +47,10 @@ bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
   return m_register_info_up->IsPAuthReg(reg);
 }
 
+bool RegisterContextPOSIX_arm64::IsTLS(unsigned reg) const {
+  return m_register_info_up->IsTLSReg(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 7c301599d3af6e..6a935274fc40d4 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -55,6 +55,7 @@ class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
 
   bool IsSVE(unsigned reg) const;
   bool IsPAuth(unsigned reg) const;
+  bool IsTLS(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/Utility/RegisterInfoPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 8505ebfa9eb971..5de7cfea14c1b2 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -119,6 +119,7 @@ class RegisterInfoPOSIX_arm64
   bool IsSSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSSVE); }
   bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
   bool IsMTEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskMTE); }
+  bool IsTLSEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskTLS); }
 
   bool IsSVEReg(unsigned reg) const;
   bool IsSVEZReg(unsigned reg) const;

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 22a9996b1a6e93..38abd8f8f2b116 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -34,6 +34,12 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
   if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2)
     opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
 
+  DataExtractor tls_data = getRegset(notes, arch.GetTriple(), AARCH64_TLS_Desc);
+  // A valid note will always contain at least one register, "tpidr". It may
+  // expand in future.
+  if (tls_data.GetByteSize() >= sizeof(uint64_t))
+    opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
+
   auto register_info_up =
       std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
   return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
@@ -59,6 +65,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
   if (m_register_info_up->IsPAuthEnabled())
     m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
 
+  if (m_register_info_up->IsTLSEnabled())
+    m_tls_data = getRegset(notes, target_triple, AARCH64_TLS_Desc);
+
   ConfigureRegisterContext();
 }
 
@@ -223,6 +232,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
     assert(offset < m_pac_data.GetByteSize());
     value.SetFromMemoryData(*reg_info, m_pac_data.GetDataStart() + offset,
                             reg_info->byte_size, lldb::eByteOrderLittle, error);
+  } else if (IsTLS(reg)) {
+    offset = reg_info->byte_offset - m_register_info_up->GetTLSOffset();
+    assert(offset < m_tls_data.GetByteSize());
+    value.SetFromMemoryData(*reg_info, m_tls_data.GetDataStart() + offset,
+                            reg_info->byte_size, lldb::eByteOrderLittle, error);
   } else
     return false;
 

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index f8548562adba3c..5e0e29f0de7fde 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -57,6 +57,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
   lldb_private::DataExtractor m_fpr_data;
   lldb_private::DataExtractor m_sve_data;
   lldb_private::DataExtractor m_pac_data;
+  lldb_private::DataExtractor m_tls_data;
 
   SVEState m_sve_state;
   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 f6a2fbdcc9387b..3d53a5795ef3eb 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -123,6 +123,10 @@ constexpr RegsetDesc AARCH64_PAC_Desc[] = {
     {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
 };
 
+constexpr RegsetDesc AARCH64_TLS_Desc[] = {
+    {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_TLS},
+};
+
 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/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index c5de5f013bbe1d..4ff288ad49c015 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -304,10 +304,10 @@ def test_aarch64_regs(self):
         values = {}
         values["x1"] = "0x000000000000002f"
         values["w1"] = "0x0000002f"
-        values["fp"] = "0x0000007fc5dd7f20"
-        values["lr"] = "0x0000000000400180"
-        values["sp"] = "0x0000007fc5dd7f00"
-        values["pc"] = "0x000000000040014c"
+        values["fp"] = "0x0000ffffdab7c770"
+        values["lr"] = "0x000000000040019c"
+        values["sp"] = "0x0000ffffdab7c750"
+        values["pc"] = "0x0000000000400168"
         values[
             "v0"
         ] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
@@ -366,6 +366,7 @@ def test_aarch64_regs(self):
         values["d31"] = "1.3980432860952889E-76"
         values["fpsr"] = "0x00000000"
         values["fpcr"] = "0x00000000"
+        values["tpidr"] = "0x1122334455667788"
 
         for regname, value in values.items():
             self.expect(

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.c b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.c
index 475e1ac93f884d..32d4773163d117 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.c
+++ b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.c
@@ -1,6 +1,8 @@
 // compile with -march=armv8-a+simd on compatible aarch64 compiler
 // linux-aarch64-neon.core was generated by: aarch64-linux-gnu-gcc-8
 // commandline: -march=armv8-a+simd -nostdlib -static -g linux-aarch64-neon.c
+#include <stdint.h>
+
 static void bar(char *boom) {
   char F = 'b';
   asm volatile("fmov     d0,  #0.5\n\t");
@@ -14,6 +16,9 @@ static void bar(char *boom) {
   asm volatile("movi     v8.16b, #0x11\n\t");
   asm volatile("movi     v31.16b, #0x30\n\t");
 
+  uint64_t pattern = 0x1122334455667788;
+  asm volatile("msr tpidr_el0, %0" ::"r"(pattern));
+
   *boom = 47; // Frame bar
 }
 

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core
index 5444c53a896a43..19364be3b70a27 100644
Binary files a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core and b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core 
diff er

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 51af9a2e1b5594..794eec738195c5 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -135,6 +135,9 @@ Changes to the LLVM tools
 Changes to LLDB
 ---------------------------------
 
+* AArch64 Linux targets now provide access to the Thread Local Storage
+  register ``tpidr``.
+
 Changes to Sanitizers
 ---------------------
 * HWASan now defaults to detecting use-after-scope bugs.


        


More information about the llvm-commits mailing list