-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[lldb][AArch64] Read fpmr register from core files #110104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) ChangesFull diff: https://github.com/llvm/llvm-project/pull/110104.diff 6 Files Affected:
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 413bf1bbdb2a58..2ddf8440aeb035 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -64,6 +64,11 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
if (zt_data.GetByteSize() >= 64)
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskZT);
+ DataExtractor fpmr_data =
+ getRegset(notes, arch.GetTriple(), AARCH64_FPMR_Desc);
+ if (fpmr_data.GetByteSize() >= sizeof(uint64_t))
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskFPMR);
+
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
@@ -128,6 +133,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
if (m_register_info_up->IsZTPresent())
m_zt_data = getRegset(notes, target_triple, AARCH64_ZT_Desc);
+ if (m_register_info_up->IsFPMRPresent())
+ m_fpmr_data = getRegset(notes, target_triple, AARCH64_FPMR_Desc);
+
ConfigureRegisterContext();
}
@@ -370,6 +378,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
*reg_info, reinterpret_cast<uint8_t *>(&m_sme_pseudo_regs) + offset,
reg_info->byte_size, lldb_private::endian::InlHostByteOrder(), error);
}
+ } else if (IsFPMR(reg)) {
+ offset = reg_info->byte_offset - m_register_info_up->GetFPMROffset();
+ assert(offset < m_fpmr_data.GetByteSize());
+ value.SetFromMemoryData(*reg_info, m_fpmr_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 ff94845e58d602..35588c40c2eb1a 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -62,6 +62,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
lldb_private::DataExtractor m_za_data;
lldb_private::DataExtractor m_mte_data;
lldb_private::DataExtractor m_zt_data;
+ lldb_private::DataExtractor m_fpmr_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 12aa5f72371c51..b97279b0d735b8 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -144,6 +144,10 @@ constexpr RegsetDesc AARCH64_MTE_Desc[] = {
llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL},
};
+constexpr RegsetDesc AARCH64_FPMR_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_FPMR},
+};
+
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/fpmr/TestAArch64LinuxFPMR.py b/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
index d022c8eb3d6cc4..7f8dc811c5df36 100644
--- a/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
+++ b/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
@@ -11,9 +11,13 @@
class AArch64LinuxFPMR(TestBase):
NO_DEBUG_INFO_TESTCASE = True
+ # The value set by the inferior.
+ EXPECTED_FPMR = (0b101010 << 32) | 0b101
+ EXPECTED_FPMR_FIELDS = ["LSCALE2 = 42", "F8S1 = FP8_E4M3 | 0x4"]
+
@skipUnlessArch("aarch64")
@skipUnlessPlatform(["linux"])
- def test_fpmr_register(self):
+ def test_fpmr_register_live(self):
if not self.isAArch64FPMR():
self.skipTest("FPMR must be present.")
@@ -39,16 +43,16 @@ def test_fpmr_register(self):
)
# This has been set by the program.
- expected_fpmr = (0b101010 << 32) | 0b101
self.expect(
"register read --all",
- substrs=["Floating Point Mode Register", f"fpmr = {expected_fpmr:#018x}"],
+ substrs=[
+ "Floating Point Mode Register",
+ f"fpmr = {self.EXPECTED_FPMR:#018x}",
+ ],
)
if self.hasXMLSupport():
- self.expect(
- "register read fpmr", substrs=["LSCALE2 = 42", "F8S1 = FP8_E4M3 | 0x4"]
- )
+ self.expect("register read fpmr", substrs=self.EXPECTED_FPMR_FIELDS)
# Write a value for the program to find. Same fields but with bit values
# inverted.
@@ -61,3 +65,19 @@ def test_fpmr_register(self):
# 0 means the program found the new value in the sysreg as expected.
self.expect("continue", substrs=["exited with status = 0"])
+
+ @skipIfLLVMTargetMissing("AArch64")
+ def test_fpmr_register_core(self):
+ if not self.isAArch64FPMR():
+ self.skipTest("FPMR must be present.")
+
+ self.runCmd("target create --core corefile")
+
+ self.expect(
+ "register read --all",
+ substrs=[
+ "Floating Point Mode Register",
+ f"fpmr = {self.EXPECTED_FPMR:#018x}",
+ ],
+ )
+ self.expect("register read fpmr", substrs=self.EXPECTED_FPMR_FIELDS)
diff --git a/lldb/test/API/linux/aarch64/fpmr/corefile b/lldb/test/API/linux/aarch64/fpmr/corefile
new file mode 100644
index 00000000000000..8496b6a774df95
Binary files /dev/null and b/lldb/test/API/linux/aarch64/fpmr/corefile differ
diff --git a/lldb/test/API/linux/aarch64/fpmr/main.c b/lldb/test/API/linux/aarch64/fpmr/main.c
index bdb7d8f40b64dd..518609035ec845 100644
--- a/lldb/test/API/linux/aarch64/fpmr/main.c
+++ b/lldb/test/API/linux/aarch64/fpmr/main.c
@@ -37,5 +37,8 @@ int main(int argc, char *argv[]) {
uint64_t new_fpmr = get_fpmr(); // Set break point at this line.
uint64_t expected_fpmr = ((uint64_t)0b010101 << 32) | (uint64_t)0b010;
- return new_fpmr == expected_fpmr ? 0 : 1;
+ if (new_fpmr != expected_fpmr)
+ __builtin_trap();
+
+ return 0;
}
|
Last one for FPMR. I'll push the release notes directly. Thanks for reviewing! |
ping! |
ping! @omjavaid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks Good. Sorry about delayed review!
Np. I also realised I have been missing review requests on llvm-zorg for weeks too, including yours. |
https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/FPMR--Floating-point-Mode-Register for details of the register.