https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/85058
>From 33b750696a5958ae13420796e82fb9f5b2ea8fa9 Mon Sep 17 00:00:00 2001 From: David Spickett <david.spick...@linaro.org> Date: Mon, 4 Mar 2024 14:31:40 +0000 Subject: [PATCH 1/2] [lldb][FreeBSD][AArch64] Enable register field detection This extends the existing register fields support from AArch64 Linux to AArch64 FreeBSD. So you will now see output like this: ``` (lldb) register read cpsr cpsr = 0x60000200 = (N = 0, Z = 1, C = 1, V = 0, DIT = 0, SS = 0, IL = 0, SSBS = 0, D = 1, A = 0, I = 0, F = 0, nRW = 0, EL = 0, SP = 0) ``` Linux and FreeBSD both have HWCAP/HWCAP2 so the detection mechanism is the same and I've renamed the detector class to reflect that. I have confirmed that FreeBSD's treatment of CPSR (spsr as the kernel calls it) is similair enough that we can use the same field information. (see `sys/arm64/include/armreg.h` and `PSR_SETTABLE_64`) For testing I've enabled the same live process test as Linux and added a shell test using an existing FreeBSD core file. Note that the latter does not need XML support because when reading a core file we are not sending the information via target.xml, it's just internal to LLDB. --- .../FreeBSD/NativeRegisterContextFreeBSD.h | 5 ++- .../NativeRegisterContextFreeBSD_arm.cpp | 4 +-- .../NativeRegisterContextFreeBSD_arm64.cpp | 24 +++++++++++-- .../NativeRegisterContextFreeBSD_arm64.h | 2 +- .../NativeRegisterContextFreeBSD_mips64.cpp | 4 +-- .../NativeRegisterContextFreeBSD_powerpc.cpp | 4 +-- .../NativeRegisterContextFreeBSD_x86_64.cpp | 4 +-- .../Process/FreeBSD/NativeThreadFreeBSD.cpp | 4 +++ .../Process/FreeBSD/NativeThreadFreeBSD.h | 2 ++ .../NativeRegisterContextLinux_arm64.cpp | 16 ++++----- .../Plugins/Process/Utility/CMakeLists.txt | 2 +- ...64.cpp => RegisterFlagsDetector_arm64.cpp} | 36 ++++++++++--------- ..._arm64.h => RegisterFlagsDetector_arm64.h} | 16 ++++----- .../RegisterContextPOSIXCore_arm64.cpp | 18 +++++----- .../elf-core/RegisterContextPOSIXCore_arm64.h | 4 +-- .../register_command/TestRegisters.py | 2 +- .../Core/aarch64-freebsd-register-fields.test | 15 ++++++++ llvm/docs/ReleaseNotes.rst | 3 ++ .../source/Plugins/Process/Utility/BUILD.gn | 2 +- 19 files changed, 107 insertions(+), 60 deletions(-) rename lldb/source/Plugins/Process/Utility/{RegisterFlagsLinux_arm64.cpp => RegisterFlagsDetector_arm64.cpp} (85%) rename lldb/source/Plugins/Process/Utility/{RegisterFlagsLinux_arm64.h => RegisterFlagsDetector_arm64.h} (85%) create mode 100644 lldb/test/Shell/Register/Core/aarch64-freebsd-register-fields.test diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h index 0000484beac99..b7f659ef24de2 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h @@ -9,14 +9,13 @@ #ifndef lldb_NativeRegisterContextFreeBSD_h #define lldb_NativeRegisterContextFreeBSD_h -#include "lldb/Host/common/NativeThreadProtocol.h" - #include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h" namespace lldb_private { namespace process_freebsd { class NativeProcessFreeBSD; +class NativeThreadFreeBSD; class NativeRegisterContextFreeBSD : public virtual NativeRegisterContextRegisterInfo { @@ -28,7 +27,7 @@ class NativeRegisterContextFreeBSD // executable. static NativeRegisterContextFreeBSD * CreateHostNativeRegisterContextFreeBSD(const ArchSpec &target_arch, - NativeThreadProtocol &native_thread); + NativeThreadFreeBSD &native_thread); virtual llvm::Error CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) = 0; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp index 2c50176643878..f19085600d6c9 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp @@ -29,12 +29,12 @@ using namespace lldb_private::process_freebsd; NativeRegisterContextFreeBSD * NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) { return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread); } NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) : NativeRegisterContextRegisterInfo( native_thread, new RegisterInfoPOSIX_arm(target_arch)) {} diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp index 9db5970af653e..28ea8b7ac1182 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp @@ -16,6 +16,7 @@ #include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" +#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" // clang-format off @@ -28,14 +29,29 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_freebsd; +// A NativeRegisterContext is constructed per thread, but all threads' registers +// will contain the same fields. Therefore this mutex prevents each instance +// competing with the other, and subsequent instances from having to detect the +// fields all over again. +static std::mutex g_register_flags_detector_mutex; +static Arm64RegisterFlagsDetector g_register_flags_detector; + NativeRegisterContextFreeBSD * NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) { + std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex); + if (!g_register_flags_detector.HasDetected()) { + NativeProcessFreeBSD &process = native_thread.GetProcess(); + g_register_flags_detector.DetectFields( + process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0), + process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0)); + } + return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread); } NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) : NativeRegisterContextRegisterInfo( native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0)) #ifdef LLDB_HAS_FREEBSD_WATCHPOINT @@ -43,6 +59,10 @@ NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64( m_read_dbreg(false) #endif { + g_register_flags_detector.UpdateRegisterInfo( + GetRegisterInfoInterface().GetRegisterInfo(), + GetRegisterInfoInterface().GetRegisterCount()); + ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs)); ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs)); } diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h index 799209e26e868..ba876006c6c53 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h @@ -37,7 +37,7 @@ class NativeRegisterContextFreeBSD_arm64 public NativeRegisterContextDBReg_arm64 { public: NativeRegisterContextFreeBSD_arm64(const ArchSpec &target_arch, - NativeThreadProtocol &native_thread); + NativeThreadFreeBSD &native_thread); uint32_t GetRegisterSetCount() const override; diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp index 0349f13945e31..090d0f3802c3b 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp @@ -30,12 +30,12 @@ using namespace lldb_private::process_freebsd; NativeRegisterContextFreeBSD * NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) { return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread); } NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) : NativeRegisterContextRegisterInfo( native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {} diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp index bdb57251f706a..fd5eb1ee2a1c8 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp @@ -67,7 +67,7 @@ static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = { NativeRegisterContextFreeBSD * NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) { return new NativeRegisterContextFreeBSD_powerpc(target_arch, native_thread); } @@ -83,7 +83,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) { } NativeRegisterContextFreeBSD_powerpc::NativeRegisterContextFreeBSD_powerpc( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) : NativeRegisterContextRegisterInfo( native_thread, CreateRegisterInfoInterface(target_arch)) {} diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp index f4171a134aeb7..5eed2d02b0a8c 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp @@ -237,7 +237,7 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { NativeRegisterContextFreeBSD * NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) { return new NativeRegisterContextFreeBSD_x86_64(target_arch, native_thread); } @@ -258,7 +258,7 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) { } NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64( - const ArchSpec &target_arch, NativeThreadProtocol &native_thread) + const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) : NativeRegisterContextRegisterInfo( native_thread, CreateRegisterInfoInterface(target_arch)), NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) { diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp index 449ec27e0da8f..a0de7751c7e55 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp @@ -316,6 +316,10 @@ NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) { return s; } +NativeProcessFreeBSD &NativeThreadFreeBSD::GetProcess() { + return static_cast<NativeProcessFreeBSD &>(m_process); +} + llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> NativeThreadFreeBSD::GetSiginfo() const { Log *log = GetLog(POSIXLog::Process); diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h index 6294a7a709635..edfb07658e19c 100644 --- a/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h +++ b/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h @@ -47,6 +47,8 @@ class NativeThreadFreeBSD : public NativeThreadProtocol { Status RemoveHardwareBreakpoint(lldb::addr_t addr) override; + NativeProcessFreeBSD &GetProcess(); + llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> GetSiginfo() const override; diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 5397e90022f39..8892394c7bfa9 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -23,7 +23,7 @@ #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h" -#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h" +#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" // System includes - They have to be included after framework includes because @@ -72,8 +72,8 @@ using namespace lldb_private::process_linux; // will contain the same fields. Therefore this mutex prevents each instance // competing with the other, and subsequent instances from having to detect the // fields all over again. -static std::mutex g_register_flags_mutex; -static LinuxArm64RegisterFlags g_register_flags; +static std::mutex g_register_flags_detector_mutex; +static Arm64RegisterFlagsDetector g_register_flags_detector; std::unique_ptr<NativeRegisterContextLinux> NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( @@ -144,10 +144,10 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS); - std::lock_guard<std::mutex> lock(g_register_flags_mutex); - if (!g_register_flags.HasDetected()) - g_register_flags.DetectFields(auxv_at_hwcap.value_or(0), - auxv_at_hwcap2.value_or(0)); + std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex); + if (!g_register_flags_detector.HasDetected()) + g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0), + auxv_at_hwcap2.value_or(0)); auto register_info_up = std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets); @@ -171,7 +171,7 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64( : NativeRegisterContextRegisterInfo(native_thread, register_info_up.release()), NativeRegisterContextLinux(native_thread) { - g_register_flags.UpdateRegisterInfo( + g_register_flags_detector.UpdateRegisterInfo( GetRegisterInfoInterface().GetRegisterInfo(), GetRegisterInfoInterface().GetRegisterCount()); diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt index 37b53b7e3e7ed..5df4a9e5ac5c8 100644 --- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -47,7 +47,7 @@ add_lldb_library(lldbPluginProcessUtility RegisterContextThreadMemory.cpp RegisterContextWindows_i386.cpp RegisterContextWindows_x86_64.cpp - RegisterFlagsLinux_arm64.cpp + RegisterFlagsDetector_arm64.cpp RegisterInfos_x86_64_with_base_shared.cpp RegisterInfoPOSIX_arm.cpp RegisterInfoPOSIX_arm64.cpp diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp similarity index 85% rename from lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp rename to lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp index 8ed75d700f225..024c6ad208689 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp @@ -1,4 +1,4 @@ -//===-- RegisterFlagsLinux_arm64.cpp --------------------------------------===// +//===-- RegisterFlagsDetector_arm64.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,11 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "RegisterFlagsLinux_arm64.h" +#include "RegisterFlagsDetector_arm64.h" #include "lldb/lldb-private-types.h" // This file is built on all systems because it is used by native processes and // core files, so we manually define the needed HWCAP values here. +// These values are the same for Linux and FreeBSD. #define HWCAP_FPHP (1ULL << 9) #define HWCAP_ASIMDHP (1ULL << 10) @@ -25,8 +26,8 @@ using namespace lldb_private; -LinuxArm64RegisterFlags::Fields -LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { (void)hwcap; if (!(hwcap2 & HWCAP2_SME)) @@ -41,8 +42,9 @@ LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { }; } -LinuxArm64RegisterFlags::Fields -LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) { +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, + uint64_t hwcap2) { (void)hwcap; if (!(hwcap2 & HWCAP2_MTE)) @@ -57,8 +59,8 @@ LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) { {"TAGGED_ADDR_ENABLE", 0}}; } -LinuxArm64RegisterFlags::Fields -LinuxArm64RegisterFlags::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) { +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) { std::vector<RegisterFlags::Field> fpcr_fields{ {"AHP", 26}, {"DN", 25}, {"FZ", 24}, {"RMode", 22, 23}, // Bits 21-20 are "Stride" which is unused in AArch64 state. @@ -93,8 +95,8 @@ LinuxArm64RegisterFlags::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) { return fpcr_fields; } -LinuxArm64RegisterFlags::Fields -LinuxArm64RegisterFlags::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) { +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) { // fpsr's contents are constant. (void)hwcap; (void)hwcap2; @@ -113,8 +115,8 @@ LinuxArm64RegisterFlags::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) { }; } -LinuxArm64RegisterFlags::Fields -LinuxArm64RegisterFlags::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) { +Arm64RegisterFlagsDetector::Fields +Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) { // The fields here are a combination of the Arm manual's SPSR_EL1, // plus a few changes where Linux has decided not to make use of them at all, // or at least not from userspace. @@ -131,7 +133,7 @@ LinuxArm64RegisterFlags::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) { cpsr_fields.push_back({"DIT", 24}); // UAO and PAN are bits 23 and 22 and have no meaning for userspace so - // are treated as reserved by the kernel. + // are treated as reserved by the kernels. cpsr_fields.push_back({"SS", 21}); cpsr_fields.push_back({"IL", 20}); @@ -159,14 +161,14 @@ LinuxArm64RegisterFlags::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) { return cpsr_fields; } -void LinuxArm64RegisterFlags::DetectFields(uint64_t hwcap, uint64_t hwcap2) { +void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2) { for (auto ® : m_registers) reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2)); m_has_detected = true; } -void LinuxArm64RegisterFlags::UpdateRegisterInfo(const RegisterInfo *reg_info, - uint32_t num_regs) { +void Arm64RegisterFlagsDetector::UpdateRegisterInfo( + const RegisterInfo *reg_info, uint32_t num_regs) { assert(m_has_detected && "Must call DetectFields before updating register info."); @@ -206,4 +208,4 @@ void LinuxArm64RegisterFlags::UpdateRegisterInfo(const RegisterInfo *reg_info, // We do not assert that search_registers is empty here, because it may // contain registers from optional extensions that are not present on the // current target. -} \ No newline at end of file +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h similarity index 85% rename from lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h rename to lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h index 49b1d90db64f6..922a6387d6ed0 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h @@ -1,4 +1,4 @@ -//===-- RegisterFlagsLinux_arm64.h ------------------------------*- C++ -*-===// +//===-- RegisterFlagsDetector_arm64.h ---------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSLINUX_ARM64_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSLINUX_ARM64_H +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H #include "lldb/Target/RegisterFlags.h" #include "llvm/ADT/StringRef.h" @@ -18,9 +18,9 @@ namespace lldb_private { struct RegisterInfo; /// This class manages the storage and detection of register field information -/// for Arm64 Linux registers. The same register may have different fields on -/// different CPUs. This class abstracts out the field detection process so we -/// can use it on live processes and core files. +/// for Arm64 Linux and FreeBSD registers. The same register may have different +/// fields on different CPUs. This class abstracts out the field detection +/// process so we can use it on live processes and core files. /// /// The general way to use this class is: /// * Make an instance somewhere that will last as long as the debug session @@ -33,7 +33,7 @@ struct RegisterInfo; /// This must be done in that order, and you should ensure that if multiple /// threads will reference the information, a mutex is used to make sure only /// one calls DetectFields. -class LinuxArm64RegisterFlags { +class Arm64RegisterFlagsDetector { public: /// For the registers listed in this class, detect which fields are /// present. Must be called before UpdateRegisterInfos. @@ -83,4 +83,4 @@ class LinuxArm64RegisterFlags { } // namespace lldb_private -#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSLINUX_ARM64_H \ No newline at end of file +#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 07501c10ec3c9..413bf1bbdb2a5 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -10,7 +10,7 @@ #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/Utility/AuxVector.h" -#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h" +#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h" #include "Plugins/Process/elf-core/ProcessElfCore.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Target/Thread.h" @@ -79,17 +79,19 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( ProcessElfCore *process = static_cast<ProcessElfCore *>(thread.GetProcess().get()); - if (process->GetArchitecture().GetTriple().getOS() == llvm::Triple::Linux) { + llvm::Triple::OSType os = process->GetArchitecture().GetTriple().getOS(); + if ((os == llvm::Triple::Linux) || (os == llvm::Triple::FreeBSD)) { AuxVector aux_vec(process->GetAuxvData()); - std::optional<uint64_t> auxv_at_hwcap = - aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP); + std::optional<uint64_t> auxv_at_hwcap = aux_vec.GetAuxValue( + os == llvm::Triple::FreeBSD ? AuxVector::AUXV_FREEBSD_AT_HWCAP + : AuxVector::AUXV_AT_HWCAP); std::optional<uint64_t> auxv_at_hwcap2 = aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP2); - m_linux_register_flags.DetectFields(auxv_at_hwcap.value_or(0), - auxv_at_hwcap2.value_or(0)); - m_linux_register_flags.UpdateRegisterInfo(GetRegisterInfo(), - GetRegisterCount()); + m_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0), + auxv_at_hwcap2.value_or(0)); + m_register_flags_detector.UpdateRegisterInfo(GetRegisterInfo(), + GetRegisterCount()); } m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h index 38e958851dfe2..ff94845e58d60 100644 --- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -11,7 +11,7 @@ #include "Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" -#include "Plugins/Process/Utility/RegisterFlagsLinux_arm64.h" +#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" #include "lldb/Utility/DataBufferHeap.h" @@ -75,7 +75,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 { struct sme_pseudo_regs m_sme_pseudo_regs; - lldb_private::LinuxArm64RegisterFlags m_linux_register_flags; + lldb_private::Arm64RegisterFlagsDetector m_register_flags_detector; const uint8_t *GetSVEBuffer(uint64_t offset = 0); diff --git a/lldb/test/API/commands/register/register/register_command/TestRegisters.py b/lldb/test/API/commands/register/register/register_command/TestRegisters.py index 5c4f3a4bb374c..dd887740c3c12 100644 --- a/lldb/test/API/commands/register/register/register_command/TestRegisters.py +++ b/lldb/test/API/commands/register/register/register_command/TestRegisters.py @@ -619,7 +619,7 @@ def test_info_register(self): self.expect("register info x30", substrs=["Name: lr (x30)"]) @skipIfXmlSupportMissing - @skipUnlessPlatform(["linux"]) + @skipUnlessPlatform(["linux", "freebsd"]) @skipIf(archs=no_match(["aarch64"])) def test_register_read_fields(self): """Test that when debugging a live process, we see the fields of certain diff --git a/lldb/test/Shell/Register/Core/aarch64-freebsd-register-fields.test b/lldb/test/Shell/Register/Core/aarch64-freebsd-register-fields.test new file mode 100644 index 0000000000000..0c8b52c14b964 --- /dev/null +++ b/lldb/test/Shell/Register/Core/aarch64-freebsd-register-fields.test @@ -0,0 +1,15 @@ +# RUN: %lldb -b -s %s -c %p/Inputs/aarch64-freebsd-multithread.core | FileCheck %s + +# Check that we see register fields for control registers when using a core file. +# As this is a corefile we check all fields as they will always be the same +# (on real cores they may vary). + +register read cpsr +# CHECK: cpsr = 0x60000200 +# CHECK-NEXT: = (N = 0, Z = 1, C = 1, V = 0, SS = 0, IL = 0, D = 1, A = 0, I = 0, F = 0, nRW = 0, EL = 0, SP = 0) +register read fpsr +# CHECK: fpsr = 0x00000000 +# CHECK-NEXT: = (QC = 0, IDC = 0, IXC = 0, UFC = 0, OFC = 0, DZC = 0, IOC = 0) +register read fpcr +# CHECK: fpcr = 0x02000000 +# CHECK-NEXT: = (AHP = 0, DN = 1, FZ = 0, RMode = 0, IDE = 0, IXE = 0, UFE = 0, OFE = 0, DZE = 0, IOE = 0) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 416b3952f1ac4..7e6dd37b8b721 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -367,6 +367,9 @@ Changes to the LLVM tools Changes to LLDB --------------------------------- +* Register field information is now provided on AArch64 FreeBSD for live + processes and core files (previously only provided on AArch64 Linux). + Changes to Sanitizers --------------------- diff --git a/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn index 4d98de81f3c26..acf279bf16373 100644 --- a/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/source/Plugins/Process/Utility/BUILD.gn @@ -66,7 +66,7 @@ static_library("Utility") { "RegisterContextWindows_i386.cpp", "RegisterContextWindows_x86_64.cpp", "RegisterContext_x86.cpp", - "RegisterFlagsLinux_arm64.cpp", + "RegisterFlagsDetector_arm64.cpp", "RegisterInfoPOSIX_arm.cpp", "RegisterInfoPOSIX_arm64.cpp", "RegisterInfoPOSIX_loongarch64.cpp", >From 4235f26d8c7c25e54f91da0686087e4486c7b010 Mon Sep 17 00:00:00 2001 From: David Spickett <david.spick...@linaro.org> Date: Mon, 1 Jul 2024 09:59:42 +0000 Subject: [PATCH 2/2] Update comment --- .../Process/Utility/RegisterFlagsDetector_arm64.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h index 922a6387d6ed0..a5bb38670b9cd 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h @@ -17,12 +17,12 @@ namespace lldb_private { struct RegisterInfo; -/// This class manages the storage and detection of register field information -/// for Arm64 Linux and FreeBSD registers. The same register may have different -/// fields on different CPUs. This class abstracts out the field detection -/// process so we can use it on live processes and core files. +/// This class manages the storage and detection of register field information. +/// The same register may have different fields on different CPUs. This class +/// abstracts out the field detection process so we can use it on live processes +/// and core files. /// -/// The general way to use this class is: +/// The way to use this class is: /// * Make an instance somewhere that will last as long as the debug session /// (because your final register info will point to this instance). /// * Read hardware capabilities from a core note, binary, prctl, etc. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits