[Lldb-commits] [lldb] f52b895 - [lldb][AArch64] Read fpmr register from core files (#110104)

via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 24 02:28:00 PDT 2024


Author: David Spickett
Date: 2024-10-24T10:27:56+01:00
New Revision: f52b89561f2d929c0c6f37fd818229fbcad3b26c

URL: https://github.com/llvm/llvm-project/commit/f52b89561f2d929c0c6f37fd818229fbcad3b26c
DIFF: https://github.com/llvm/llvm-project/commit/f52b89561f2d929c0c6f37fd818229fbcad3b26c.diff

LOG: [lldb][AArch64] Read fpmr register from core files (#110104)

https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/FPMR--Floating-point-Mode-Register
for details of the register.

Added: 
    lldb/test/API/linux/aarch64/fpmr/corefile

Modified: 
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
    lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
    lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
    lldb/test/API/linux/aarch64/fpmr/main.c

Removed: 
    


################################################################################
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 
diff er

diff  --git a/lldb/test/API/linux/aarch64/fpmr/main.c b/lldb/test/API/linux/aarch64/fpmr/main.c
index bdb7d8f40b64dd..0a9a9c53eb7888 100644
--- a/lldb/test/API/linux/aarch64/fpmr/main.c
+++ b/lldb/test/API/linux/aarch64/fpmr/main.c
@@ -37,5 +37,10 @@ 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 the debugger failed to update the value, exit uncleanly.
+  // This also allows you to run this program standalone to create a core file.
+  if (new_fpmr != expected_fpmr)
+    __builtin_trap();
+
+  return 0;
 }


        


More information about the lldb-commits mailing list