diff --git a/lldb/include/lldb/Host/linux/Ptrace.h b/lldb/include/lldb/Host/linux/Ptrace.h --- a/lldb/include/lldb/Host/linux/Ptrace.h +++ b/lldb/include/lldb/Host/linux/Ptrace.h @@ -57,6 +57,4 @@ #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.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -55,6 +55,7 @@ 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/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -47,6 +47,10 @@ 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 register_info) diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h --- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -119,6 +119,7 @@ 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.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -57,6 +57,7 @@ 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/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -34,6 +34,12 @@ 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(arch, opt_regsets); return std::unique_ptr( @@ -59,6 +65,9 @@ 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 @@ 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/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h --- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h @@ -123,6 +123,10 @@ {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 --- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -304,10 +304,10 @@ 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 @@ 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 --- 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 + static void bar(char *boom) { char F = 'b'; asm volatile("fmov d0, #0.5\n\t"); @@ -14,6 +16,9 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@