[Lldb-commits] [lldb] [lldb][AArch64] Add HWCAP3 to register field detection (PR #145029)
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Fri Jun 20 05:24:37 PDT 2025
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/145029
This will be used to detect the presence of Arm's new Memory Tagging store only checking feature. This commit just adds the plumbing to get that value into the detection function.
FreeBSD has not allocated a number for HWCAP3 and already has AT_ARGV defined as 29. So instead of attempting to read from FreeBSD processes, I've explicitly passed nullopt. We don't want to be reading some other entry accidentally.
If/when FreeBSD adds HWCAP3 we can handle it like we do for AUXV_FREEBSD_AT_HWCAP.
No extra tests here, those will be coming with the next change for MTE support.
>From e7d5ab3673edf96892d9aff05b440bc70b0fb0f3 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Thu, 19 Jun 2025 10:43:48 +0000
Subject: [PATCH] [lldb][AArch64] Add HWCAP3 to register field detection
This will be used to detect the presence of Arm's new Memory
Tagging store only checking feature.
This commit just adds the plubming to get that value into
the detection function.
FreeBSD has not allocated a number for HWCAP3 and already
has AT_ARGV defined as 29. So instead of attempting to read
from FreeBSD processes, I've explictly passed nullopt.
We don't want to be reading some other entry accidentally.
If/when FreeBSD adds HWCAP3 we can handle it like we do for
AUXV_FREEBSD_AT_HWCAP.
No extra tests here, those will be coming with the next
change for MTE support.
---
.../NativeRegisterContextFreeBSD_arm64.cpp | 3 +-
.../NativeRegisterContextLinux_arm64.cpp | 5 ++-
.../Plugins/Process/Utility/AuxVector.cpp | 1 +
.../Plugins/Process/Utility/AuxVector.h | 1 +
.../Utility/RegisterFlagsDetector_arm64.cpp | 36 +++++++++++++------
.../Utility/RegisterFlagsDetector_arm64.h | 25 ++++++++-----
.../RegisterContextPOSIXCore_arm64.cpp | 13 ++++---
7 files changed, 59 insertions(+), 25 deletions(-)
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index 7adc00622ec2d..0e23a3acbaa82 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
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));
+ process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0),
+ /*hwcap3=*/std::nullopt);
}
return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 884c7d4b9e359..b1c7421bef8d5 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -162,10 +162,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
+ std::optional<uint64_t> auxv_at_hwcap3 =
+ process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3);
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));
+ auxv_at_hwcap2.value_or(0),
+ auxv_at_hwcap3.value_or(0));
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp
index f495ffb1924e7..50500a8593e1d 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp
@@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const {
case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break;
case ENTRY_NAME(AUXV_AT_RANDOM); break;
case ENTRY_NAME(AUXV_AT_HWCAP2); break;
+ case ENTRY_NAME(AUXV_AT_HWCAP3); break;
case ENTRY_NAME(AUXV_AT_EXECFN); break;
case ENTRY_NAME(AUXV_AT_SYSINFO); break;
case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break;
diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h
index 2670b34f6b0af..7733e0ffc6832 100644
--- a/lldb/source/Plugins/Process/Utility/AuxVector.h
+++ b/lldb/source/Plugins/Process/Utility/AuxVector.h
@@ -57,6 +57,7 @@ class AuxVector {
AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes.
AUXV_AT_HWCAP2 = 26, ///< Extension of AT_HWCAP.
+ AUXV_AT_HWCAP3 = 29, ///< Extension of AT_HWCAP.
AUXV_AT_EXECFN = 31, ///< Filename of executable.
AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system
/// calls and other nice things.
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
index 042940b7dff6e..d339a59689f7f 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
@@ -29,8 +29,10 @@
using namespace lldb_private;
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap;
+ (void)hwcap3;
if (!(hwcap2 & HWCAP2_FPMR))
return {};
@@ -53,8 +55,10 @@ Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
Arm64RegisterFlagsDetector::Fields
Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
- uint64_t hwcap2) {
+ uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap2;
+ (void)hwcap3;
if (!(hwcap & HWCAP_GCS))
return {};
@@ -67,8 +71,10 @@ Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap;
+ (void)hwcap3;
if (!(hwcap2 & HWCAP2_SME))
return {};
@@ -83,9 +89,10 @@ Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
- uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
(void)hwcap;
+ (void)hwcap3;
if (!(hwcap2 & HWCAP2_MTE))
return {};
@@ -103,7 +110,10 @@ Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
+ (void)hwcap3;
+
static const FieldEnum rmode_enum(
"rmode_enum", {{0, "RN"}, {1, "RP"}, {2, "RM"}, {3, "RZ"}});
@@ -142,10 +152,12 @@ Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
// fpsr's contents are constant.
(void)hwcap;
(void)hwcap2;
+ (void)hwcap3;
return {
// Bits 31-28 are N/Z/C/V, only used by AArch32.
@@ -162,7 +174,10 @@ Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
}
Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
+Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
+ (void)hwcap3;
+
// 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.
@@ -207,9 +222,10 @@ Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
return cpsr_fields;
}
-void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2) {
+void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3) {
for (auto ® : m_registers)
- reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2));
+ reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2, hwcap3));
m_has_detected = true;
}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
index 7daebcc71db04..aec2bf9f4886f 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
@@ -40,7 +40,7 @@ class Arm64RegisterFlagsDetector {
/// If called more than once, fields will be redetected each time from
/// scratch. If the target would not have this register at all, the list of
/// fields will be left empty.
- void DetectFields(uint64_t hwcap, uint64_t hwcap2);
+ void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);
/// Add the field information of any registers named in this class,
/// to the relevant RegisterInfo instances. Note that this will be done
@@ -53,15 +53,22 @@ class Arm64RegisterFlagsDetector {
private:
using Fields = std::vector<RegisterFlags::Field>;
- using DetectorFn = std::function<Fields(uint64_t, uint64_t)>;
+ using DetectorFn = std::function<Fields(uint64_t, uint64_t, uint64_t)>;
- static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2);
- static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
+ static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2,
+ uint64_t hwcap3);
struct RegisterEntry {
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index bd02bb0e69a4d..d5046d369ab2f 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -96,14 +96,19 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
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(
- os == llvm::Triple::FreeBSD ? AuxVector::AUXV_FREEBSD_AT_HWCAP
- : AuxVector::AUXV_AT_HWCAP);
+ bool is_freebsd = os == llvm::Triple::FreeBSD;
+ std::optional<uint64_t> auxv_at_hwcap =
+ aux_vec.GetAuxValue(is_freebsd ? AuxVector::AUXV_FREEBSD_AT_HWCAP
+ : AuxVector::AUXV_AT_HWCAP);
std::optional<uint64_t> auxv_at_hwcap2 =
aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP2);
+ std::optional<uint64_t> auxv_at_hwcap3 =
+ is_freebsd ? std::nullopt
+ : aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP3);
m_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
- auxv_at_hwcap2.value_or(0));
+ auxv_at_hwcap2.value_or(0),
+ auxv_at_hwcap3.value_or(0));
m_register_flags_detector.UpdateRegisterInfo(GetRegisterInfo(),
GetRegisterCount());
}
More information about the lldb-commits
mailing list