llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) <details> <summary>Changes</summary> The ZT0 register is always 64 bytes in size so it is a lot easier to handle than ZA which is scalable. In addition, reading an inactive ZT0 via ptrace returns all 0s, unlike ZA which returns no register data. This means that a corefile from a process where ZA and ZT0 were inactive still contains an NT_ARM_ZT note and we can simply say that if it's there, then we should be able to read from it. Along the way I removed a redundant check on the size of the ZA note. If that note's size is < the ZA header size, we do not have SME, and therefore could not have SME2 either. I have added ZT0 to the existing SME core files tests. This means that you need an SME2 system to generate them (Arm's FVP at this point). I think this is a fair tradeoff given that this is all running in simulation anyway and seperate ZT0 tests would be 99% identical copies of the ZA only tests. --- Full diff: https://github.com/llvm/llvm-project/pull/70934.diff 9 Files Affected: - (modified) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp (+23-13) - (modified) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h (+1) - (modified) lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py (+5) - (modified) lldb/test/API/linux/aarch64/sme_core_file/core_0_16_32_1 () - (modified) lldb/test/API/linux/aarch64/sme_core_file/core_0_32_16_0 () - (modified) lldb/test/API/linux/aarch64/sme_core_file/core_1_16_32_0 () - (modified) lldb/test/API/linux/aarch64/sme_core_file/core_1_32_16_1 () - (added) lldb/test/API/linux/aarch64/sme_core_file/generate.sh (+9) - (modified) lldb/test/API/linux/aarch64/sme_core_file/main.c (+23-6) ``````````diff diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index db37b7cbb99d7e8..85073b56f64bf79 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -54,6 +54,13 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch, if (mte_data.GetByteSize() >= sizeof(uint64_t)) opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskMTE); + DataExtractor zt_data = getRegset(notes, arch.GetTriple(), AARCH64_ZT_Desc); + // Although ZT0 can be in a disabled state like ZA can, the kernel reports + // its content as 0s in that state. Therefore even a disabled ZT0 will have + // a note containing those 0s. ZT0 is a 512 bit / 64 byte register. + if (zt_data.GetByteSize() >= 64) + opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskZT); + auto register_info_up = std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets); return std::unique_ptr<RegisterContextCorePOSIX_arm64>( @@ -98,6 +105,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( if (m_register_info_up->IsMTEPresent()) m_mte_data = getRegset(notes, target_triple, AARCH64_MTE_Desc); + if (m_register_info_up->IsZTPresent()) + m_zt_data = getRegset(notes, target_triple, AARCH64_ZT_Desc); + ConfigureRegisterContext(); } @@ -298,19 +308,7 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, if (m_za_data.GetByteSize() < sizeof(sve::user_za_header)) return false; - if (!IsSMEZA(reg)) { - offset = reg_info->byte_offset - m_register_info_up->GetSMEOffset(); - assert(offset < sizeof(m_sme_pseudo_regs)); - // Host endian since these values are derived instead of being read from a - // core file note. - value.SetFromMemoryData( - *reg_info, reinterpret_cast<uint8_t *>(&m_sme_pseudo_regs) + offset, - reg_info->byte_size, lldb_private::endian::InlHostByteOrder(), error); - } else { - // If the process did not have the SME extension. - if (m_za_data.GetByteSize() < sizeof(sve::user_za_header)) - return false; - + if (m_register_info_up->IsSMERegZA(reg)) { // Don't use the size of the note to tell whether ZA is enabled. There may // be non-register padding data after the header. Use the embedded // header's size field instead. @@ -339,6 +337,18 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, value.SetFromMemoryData(*reg_info, src + sizeof(sve::user_za_header), reg_info->byte_size, lldb::eByteOrderLittle, error); + } else if (m_register_info_up->IsSMERegZT(reg)) { + value.SetFromMemoryData(*reg_info, m_zt_data.GetDataStart(), + reg_info->byte_size, lldb::eByteOrderLittle, + error); + } else { + offset = reg_info->byte_offset - m_register_info_up->GetSMEOffset(); + assert(offset < sizeof(m_sme_pseudo_regs)); + // Host endian since these values are derived instead of being read from a + // core file note. + value.SetFromMemoryData( + *reg_info, reinterpret_cast<uint8_t *>(&m_sme_pseudo_regs) + offset, + reg_info->byte_size, lldb_private::endian::InlHostByteOrder(), 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 86bdeb426ab3fe0..95527af74fb5334 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -60,6 +60,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 { lldb_private::DataExtractor m_tls_data; lldb_private::DataExtractor m_za_data; lldb_private::DataExtractor m_mte_data; + lldb_private::DataExtractor m_zt_data; SVEState m_sve_state = SVEState::Unknown; uint16_t m_sve_vector_length = 0; diff --git a/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py b/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py index f65e64f9db739ae..a5fdd0ab2068cbb 100644 --- a/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py +++ b/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py @@ -89,14 +89,19 @@ def check_corefile(self, corefile): # Each row of ZA is set to the row number plus 1. For example: # za = {0x01 0x01 0x01 0x01 <repeat until end of row> 0x02 0x02 ... make_row = repeat_bytes + expected_zt0 = "{{{}}}".format( + " ".join(["0x{:02x}".format(i + 1) for i in range(512 // 8)]) + ) else: # When ZA is disabled lldb shows it as 0s. make_row = lambda _, n: repeat_bytes(0, n) + expected_zt0 = "{{{}}}".format(" ".join(["0x00" for i in range(512 // 8)])) expected_za = "{{{}}}".format( " ".join([make_row(i + 1, svl) for i in range(svl)]) ) self.expect("register read za", substrs=[expected_za]) + self.expect("register read zt0", substrs=[expected_zt0]) @skipIfLLVMTargetMissing("AArch64") def test_sme_core_file_ssve_vl32_svl16_za_enabled(self): diff --git a/lldb/test/API/linux/aarch64/sme_core_file/core_0_16_32_1 b/lldb/test/API/linux/aarch64/sme_core_file/core_0_16_32_1 index b7c6250324cc21e..b7345748c363741 100644 Binary files a/lldb/test/API/linux/aarch64/sme_core_file/core_0_16_32_1 and b/lldb/test/API/linux/aarch64/sme_core_file/core_0_16_32_1 differ diff --git a/lldb/test/API/linux/aarch64/sme_core_file/core_0_32_16_0 b/lldb/test/API/linux/aarch64/sme_core_file/core_0_32_16_0 index cba6c0f0738370a..713fb2384a29f43 100644 Binary files a/lldb/test/API/linux/aarch64/sme_core_file/core_0_32_16_0 and b/lldb/test/API/linux/aarch64/sme_core_file/core_0_32_16_0 differ diff --git a/lldb/test/API/linux/aarch64/sme_core_file/core_1_16_32_0 b/lldb/test/API/linux/aarch64/sme_core_file/core_1_16_32_0 index dcda36c862bfb66..9d6efd7f9c7510f 100644 Binary files a/lldb/test/API/linux/aarch64/sme_core_file/core_1_16_32_0 and b/lldb/test/API/linux/aarch64/sme_core_file/core_1_16_32_0 differ diff --git a/lldb/test/API/linux/aarch64/sme_core_file/core_1_32_16_1 b/lldb/test/API/linux/aarch64/sme_core_file/core_1_32_16_1 index 7ec49584f2b6424..9c6f2033adc10fa 100644 Binary files a/lldb/test/API/linux/aarch64/sme_core_file/core_1_32_16_1 and b/lldb/test/API/linux/aarch64/sme_core_file/core_1_32_16_1 differ diff --git a/lldb/test/API/linux/aarch64/sme_core_file/generate.sh b/lldb/test/API/linux/aarch64/sme_core_file/generate.sh new file mode 100644 index 000000000000000..5e75a5cdb8bd03b --- /dev/null +++ b/lldb/test/API/linux/aarch64/sme_core_file/generate.sh @@ -0,0 +1,9 @@ +run () { + ./a.out "$@" + mv core core_$(echo "$*" | sed 's/ /_/g') +} + +run 0 16 32 1 +run 0 32 16 0 +run 1 16 32 0 +run 1 32 16 1 diff --git a/lldb/test/API/linux/aarch64/sme_core_file/main.c b/lldb/test/API/linux/aarch64/sme_core_file/main.c index 21793a4ad63d39e..10fc92ba2fcabe0 100644 --- a/lldb/test/API/linux/aarch64/sme_core_file/main.c +++ b/lldb/test/API/linux/aarch64/sme_core_file/main.c @@ -1,16 +1,21 @@ // clang-format off // Compile with: -// clang -target aarch64-unknown-linux-gnu main.c -o a.out -g -march=armv8.6-a+sve+sme +// clang -target aarch64-unknown-linux-gnu main.c -o a.out -g -march=armv8.6-a+sve+sme+sme2 // // For minimal corefile size, do this before running the program: -// echo 0x20 > /proc/self/coredeump_filter +// echo 0x20 > /proc/self/coredump_filter // -// Must be run on a system that has SVE and SME, including the smefa64 -// extension. Example command: -// main 0 32 64 1 +// Must be run on a system that has SVE, SME and SME2, including the smefa64 +// extension. +// +// Example command: +// ./a.out 0 32 64 1 // // This would not enter streaming mode, set non-streaming VL to 32 -// bytes, streaming VL to 64 bytes and enable ZA. +// bytes, streaming VL to 64 bytes and enable ZA and ZT0. +// +// To generate all the test files, use the generate.sh script that's in this +// folder. // clang-format on #include <stdbool.h> @@ -94,6 +99,17 @@ void set_za_register(int streaming_vl) { "r"(&data) : "w12"); } +#undef MAX_VL_BYTES +} + +void set_zt0_register() { +#define ZTO_LEN (512 / 8) + uint8_t data[ZTO_LEN]; + for (unsigned i = 0; i < ZTO_LEN; ++i) + data[i] = i + 1; + + asm volatile("ldr zt0, [%0]" ::"r"(&data)); +#undef ZT0_LEN } void set_tpidr2(uint64_t value) { @@ -132,6 +148,7 @@ int main(int argc, char **argv) { if (strcmp(argv[4], "1") == 0) { SMSTART_ZA; set_za_register(streaming_vl); + set_zt0_register(); } *(volatile char *)(0) = 0; // Crashes here. `````````` </details> https://github.com/llvm/llvm-project/pull/70934 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits