[Lldb-commits] [lldb] [llvm] [lldb][FreeBSD][AArch64] Enable register field detection (PR #85058)
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Mon Jul 1 03:01:11 PDT 2024
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.spickett at 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.spickett at 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.
More information about the lldb-commits
mailing list