Skip to content

Commit 43ad521

Browse files
committed
[lldb][AArch64] Add reading of TLS tpidr register from core files
7e22921 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
1 parent 067ecad commit 43ad521

File tree

11 files changed

+38
-6
lines changed

11 files changed

+38
-6
lines changed

lldb/include/lldb/Host/linux/Ptrace.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,4 @@ typedef int __ptrace_request;
5757
#define PTRACE_POKEMTETAGS 34
5858
#endif
5959

60-
#define LLDB_PTRACE_NT_ARM_TLS 0x401 // ARM TLS register
61-
6260
#endif // liblldb_Host_linux_Ptrace_h_

lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
4747
return m_register_info_up->IsPAuthReg(reg);
4848
}
4949

50+
bool RegisterContextPOSIX_arm64::IsTLS(unsigned reg) const {
51+
return m_register_info_up->IsTLSReg(reg);
52+
}
53+
5054
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
5155
lldb_private::Thread &thread,
5256
std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)

lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
5555

5656
bool IsSVE(unsigned reg) const;
5757
bool IsPAuth(unsigned reg) const;
58+
bool IsTLS(unsigned reg) const;
5859

5960
bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
6061
bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }

lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class RegisterInfoPOSIX_arm64
119119
bool IsSSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSSVE); }
120120
bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
121121
bool IsMTEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskMTE); }
122+
bool IsTLSEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskTLS); }
122123

123124
bool IsSVEReg(unsigned reg) const;
124125
bool IsSVEZReg(unsigned reg) const;

lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
3434
if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2)
3535
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
3636

37+
DataExtractor tls_data = getRegset(notes, arch.GetTriple(), AARCH64_TLS_Desc);
38+
// A valid note will always contain at least one register, "tpidr". It may
39+
// expand in future.
40+
if (tls_data.GetByteSize() >= sizeof(uint64_t))
41+
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
42+
3743
auto register_info_up =
3844
std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
3945
return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
@@ -59,6 +65,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
5965
if (m_register_info_up->IsPAuthEnabled())
6066
m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
6167

68+
if (m_register_info_up->IsTLSEnabled())
69+
m_tls_data = getRegset(notes, target_triple, AARCH64_TLS_Desc);
70+
6271
ConfigureRegisterContext();
6372
}
6473

@@ -223,6 +232,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
223232
assert(offset < m_pac_data.GetByteSize());
224233
value.SetFromMemoryData(*reg_info, m_pac_data.GetDataStart() + offset,
225234
reg_info->byte_size, lldb::eByteOrderLittle, error);
235+
} else if (IsTLS(reg)) {
236+
offset = reg_info->byte_offset - m_register_info_up->GetTLSOffset();
237+
assert(offset < m_tls_data.GetByteSize());
238+
value.SetFromMemoryData(*reg_info, m_tls_data.GetDataStart() + offset,
239+
reg_info->byte_size, lldb::eByteOrderLittle, error);
226240
} else
227241
return false;
228242

lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
5757
lldb_private::DataExtractor m_fpr_data;
5858
lldb_private::DataExtractor m_sve_data;
5959
lldb_private::DataExtractor m_pac_data;
60+
lldb_private::DataExtractor m_tls_data;
6061

6162
SVEState m_sve_state;
6263
uint16_t m_sve_vector_length = 0;

lldb/source/Plugins/Process/elf-core/RegisterUtilities.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ constexpr RegsetDesc AARCH64_PAC_Desc[] = {
123123
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
124124
};
125125

126+
constexpr RegsetDesc AARCH64_TLS_Desc[] = {
127+
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_TLS},
128+
};
129+
126130
constexpr RegsetDesc PPC_VMX_Desc[] = {
127131
{llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
128132
{llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},

lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ def test_aarch64_regs(self):
304304
values = {}
305305
values["x1"] = "0x000000000000002f"
306306
values["w1"] = "0x0000002f"
307-
values["fp"] = "0x0000007fc5dd7f20"
308-
values["lr"] = "0x0000000000400180"
309-
values["sp"] = "0x0000007fc5dd7f00"
310-
values["pc"] = "0x000000000040014c"
307+
values["fp"] = "0x0000ffffdab7c770"
308+
values["lr"] = "0x000000000040019c"
309+
values["sp"] = "0x0000ffffdab7c750"
310+
values["pc"] = "0x0000000000400168"
311311
values[
312312
"v0"
313313
] = "{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):
366366
values["d31"] = "1.3980432860952889E-76"
367367
values["fpsr"] = "0x00000000"
368368
values["fpcr"] = "0x00000000"
369+
values["tpidr"] = "0x1122334455667788"
369370

370371
for regname, value in values.items():
371372
self.expect(

lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// compile with -march=armv8-a+simd on compatible aarch64 compiler
22
// linux-aarch64-neon.core was generated by: aarch64-linux-gnu-gcc-8
33
// commandline: -march=armv8-a+simd -nostdlib -static -g linux-aarch64-neon.c
4+
#include <stdint.h>
5+
46
static void bar(char *boom) {
57
char F = 'b';
68
asm volatile("fmov d0, #0.5\n\t");
@@ -14,6 +16,9 @@ static void bar(char *boom) {
1416
asm volatile("movi v8.16b, #0x11\n\t");
1517
asm volatile("movi v31.16b, #0x30\n\t");
1618

19+
uint64_t pattern = 0x1122334455667788;
20+
asm volatile("msr tpidr_el0, %0" ::"r"(pattern));
21+
1722
*boom = 47; // Frame bar
1823
}
1924

Binary file not shown.

llvm/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ Changes to the LLVM tools
135135
Changes to LLDB
136136
---------------------------------
137137

138+
* AArch64 Linux targets now provide access to the Thread Local Storage
139+
register ``tpidr``.
140+
138141
Changes to Sanitizers
139142
---------------------
140143
* HWASan now defaults to detecting use-after-scope bugs.

0 commit comments

Comments
 (0)