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; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits