Skip to content

[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

Merged
merged 2 commits into from
Oct 24, 2024

Conversation

DavidSpickett
Copy link
Collaborator

@DavidSpickett DavidSpickett commented Sep 26, 2024

@llvmbot
Copy link
Member

llvmbot commented Sep 26, 2024

@llvm/pr-subscribers-lldb

Author: David Spickett (DavidSpickett)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/110104.diff

6 Files Affected:

  • (modified) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp (+13)
  • (modified) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h (+1)
  • (modified) lldb/source/Plugins/Process/elf-core/RegisterUtilities.h (+4)
  • (modified) lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py (+26-6)
  • (added) lldb/test/API/linux/aarch64/fpmr/corefile ()
  • (modified) lldb/test/API/linux/aarch64/fpmr/main.c (+4-1)
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;
 }

@DavidSpickett
Copy link
Collaborator Author

Last one for FPMR. I'll push the release notes directly.

Thanks for reviewing!

@DavidSpickett
Copy link
Collaborator Author

ping!

@DavidSpickett
Copy link
Collaborator Author

ping! @omjavaid

Copy link
Contributor

@omjavaid omjavaid left a 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!

@DavidSpickett
Copy link
Collaborator Author

Np. I also realised I have been missing review requests on llvm-zorg for weeks too, including yours.

@DavidSpickett DavidSpickett merged commit f52b895 into llvm:main Oct 24, 2024
7 checks passed
@DavidSpickett DavidSpickett deleted the fpmr-pr3 branch October 24, 2024 09:28
@frobtech frobtech mentioned this pull request Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants