[Lldb-commits] [lldb] [lldb][elf-core][ARM] Add support for VFP registers (PR #155956)
Igor Kudrin via lldb-commits
lldb-commits at lists.llvm.org
Fri Aug 29 17:55:17 PDT 2025
https://github.com/igorkudrin updated https://github.com/llvm/llvm-project/pull/155956
>From b1348c5099d6071b08872b0bba67b8468c86c6fe Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Thu, 28 Aug 2025 14:39:37 -0700
Subject: [PATCH 1/2] [lldb][elf-core][ARM] Add support for VFP registers
This patch loads values of the VFP registers from the NT_ARM_VFP note.
Note that a CORE/NT_FPREGSET note is typically present in core dump
files and used to store the FPA registers. The FPA unit is rare and
obsolete; however, at least Linux and FreeBSD create the note even if
the unit is absent.
---
.../elf-core/RegisterContextPOSIXCore_arm.cpp | 21 ++++++++++++++++++
.../elf-core/RegisterContextPOSIXCore_arm.h | 1 +
.../Process/elf-core/RegisterUtilities.cpp | 2 +-
.../Process/elf-core/RegisterUtilities.h | 4 ++++
.../postmortem/elf-core/TestLinuxCore.py | 21 ++++++++++++++++++
.../postmortem/elf-core/linux-arm.core | Bin 252 -> 532 bytes
6 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 3a62081827c6a..acfa1103d62f0 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -23,6 +23,10 @@ RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
gpregset.GetByteSize());
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ const llvm::Triple &target_triple =
+ m_register_info_up->GetTargetArchitecture().GetTriple();
+ m_fpr = getRegset(notes, target_triple, ARM_VFP_Desc);
}
RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() = default;
@@ -51,6 +55,23 @@ bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info,
return true;
}
}
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return false;
+
+ if (IsFPR(reg)) {
+ assert(offset >= GetGPRSize());
+ offset -= GetGPRSize();
+ if (m_fpr.ValidOffsetForDataOfSize(offset, reg_info->byte_size)) {
+ Status error;
+ value.SetFromMemoryData(*reg_info, m_fpr.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle,
+ error);
+ return error.Success();
+ }
+ }
+
return false;
}
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index 8d773a046bcac..e466ee242181b 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -48,6 +48,7 @@ class RegisterContextCorePOSIX_arm : public RegisterContextPOSIX_arm {
private:
lldb::DataBufferSP m_gpr_buffer;
lldb_private::DataExtractor m_gpr;
+ lldb_private::DataExtractor m_fpr;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM_H
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp
index 7455d78774ee6..0100c2fdbd34b 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp
@@ -16,7 +16,7 @@ static std::optional<uint32_t>
getNoteType(const llvm::Triple &Triple,
llvm::ArrayRef<RegsetDesc> RegsetDescs) {
for (const auto &Entry : RegsetDescs) {
- if (Entry.OS != Triple.getOS())
+ if (Entry.OS != llvm::Triple::UnknownOS && Entry.OS != Triple.getOS())
continue;
if (Entry.Arch != llvm::Triple::UnknownArch &&
Entry.Arch != Triple.getArch())
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index 59382a12cde0a..645ec363768e9 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -152,6 +152,10 @@ constexpr RegsetDesc AARCH64_GCS_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_GCS},
};
+constexpr RegsetDesc ARM_VFP_Desc[] = {
+ {llvm::Triple::UnknownOS, llvm::Triple::arm, llvm::ELF::NT_ARM_VFP},
+};
+
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 a68175dc4e4d7..d8b389fab0170 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -688,6 +688,27 @@ def test_arm_core(self):
values["lr"] = "0x0000000e"
values["pc"] = "0x0000000f"
values["cpsr"] = "0x00000010"
+ for i in range(32):
+ values["s" + str(i)] = str(i)
+ values["fpscr"] = "0x12345678"
+ values["d0"] = "0.0078125"
+ values["d1"] = "32.000007629394531"
+ values["d2"] = "2048.0004920959473"
+ values["d3"] = "32768.007904052734"
+ values["d4"] = "262144.0634765625"
+ values["d5"] = "1048576.2543945313"
+ values["d6"] = "4194305.01953125"
+ values["d7"] = "16777220.0859375"
+ values["d8"] = "50331656.1875"
+ values["d9"] = "100663312.390625"
+ values["d10"] = "201326624.8125"
+ values["d11"] = "402653249.6875"
+ values["d12"] = "805306499.5"
+ values["d13"] = "1610612999.25"
+ values["d14"] = "3221225999"
+ values["d15"] = "6442451999"
+ for i in range(16, 32):
+ values["d" + str(i)] = str(i)
for regname, value in values.items():
self.expect(
"register read {}".format(regname),
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-arm.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-arm.core
index a919a9d6ae66667f781743e60ca338edee61effe..be501a56c1c8c1811bbf4059afb1b3225fefc744 100644
GIT binary patch
literal 532
zcmYk$zfZzI7{>9d)*tu-fyA8+M${^bA~gmR69UAjar94MG%j{@bZ~I&=;&yiIyy2s
zGBUF1==W_O2$z2P+`YZKw@>ZPh39#TPQ!Oq=V=~Hi)7%+v%1gvdhS~?J)qhW`3fta
z_paJjUbmOVY+mACG}u_#&OX|i$(MC-uJE{$=Af80h<~%+wABJ^Wjn3kGHmxMa#(})
z*}x|9*g^qC&^A5e+httRx$NHDG0jHQB10ZTh>>6fcg8I!qlOTD++%<U&v?NbV!Y!6
zpGfeHA$~Bz7!&-#MlDRk?I?GZd&)q$uRKuJm50hBWkY$aJW)24r^;6Na2u5V0Z7R$
A-2eap
delta 12
TcmbQj@`rJP3)2dQiEi5f9j*kS
>From bc1482b9f75a5347f30fafc9a4c2c5aa72c6a405 Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Fri, 29 Aug 2025 17:52:58 -0700
Subject: [PATCH 2/2] fixup! Rework
RegisterContextCorePOSIX_arm::ReadRegister()
---
.../elf-core/RegisterContextPOSIXCore_arm.cpp | 30 ++++++++-----------
1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index acfa1103d62f0..c9e90ebf8a4dd 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -47,29 +47,23 @@ bool RegisterContextCorePOSIX_arm::WriteFPR() {
bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
- lldb::offset_t offset = reg_info->byte_offset;
- if (offset + reg_info->byte_size <= GetGPRSize()) {
- uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
- if (offset == reg_info->byte_offset + reg_info->byte_size) {
- value = v;
- return true;
- }
- }
-
const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
if (reg == LLDB_INVALID_REGNUM)
return false;
- if (IsFPR(reg)) {
- assert(offset >= GetGPRSize());
- offset -= GetGPRSize();
- if (m_fpr.ValidOffsetForDataOfSize(offset, reg_info->byte_size)) {
- Status error;
- value.SetFromMemoryData(*reg_info, m_fpr.GetDataStart() + offset,
- reg_info->byte_size, lldb::eByteOrderLittle,
- error);
- return error.Success();
+ if (IsGPR(reg)) {
+ lldb::offset_t offset = reg_info->byte_offset;
+ if (m_gpr.ValidOffsetForDataOfSize(offset, reg_info->byte_size)) {
+ value = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+ return offset == reg_info->byte_offset + reg_info->byte_size;
}
+ } else if (IsFPR(reg)) {
+ assert(reg_info->byte_offset >= GetGPRSize());
+ lldb::offset_t offset = reg_info->byte_offset - GetGPRSize();
+ if (m_fpr.ValidOffsetForDataOfSize(offset, reg_info->byte_size))
+ return value
+ .SetValueFromData(*reg_info, m_fpr, offset, /*partial_data_ok=*/false)
+ .Success();
}
return false;
More information about the lldb-commits
mailing list