Skip to content

Commit 9ad630f

Browse files
DavidSpicketttru
authored andcommitted
[lldb][AArch64] Add HWCAP3 to register field detection (#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 0. 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. (cherry picked from commit d26ca8b)
1 parent 6145440 commit 9ad630f

File tree

7 files changed

+59
-25
lines changed

7 files changed

+59
-25
lines changed

lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
4444
NativeProcessFreeBSD &process = native_thread.GetProcess();
4545
g_register_flags_detector.DetectFields(
4646
process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0),
47-
process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0));
47+
process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0),
48+
/*hwcap3=*/0);
4849
}
4950

5051
return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,13 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
162162

163163
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskTLS);
164164

165+
std::optional<uint64_t> auxv_at_hwcap3 =
166+
process.GetAuxValue(AuxVector::AUXV_AT_HWCAP3);
165167
std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
166168
if (!g_register_flags_detector.HasDetected())
167169
g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
168-
auxv_at_hwcap2.value_or(0));
170+
auxv_at_hwcap2.value_or(0),
171+
auxv_at_hwcap3.value_or(0));
169172

170173
auto register_info_up =
171174
std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);

lldb/source/Plugins/Process/Utility/AuxVector.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const char *AuxVector::GetEntryName(EntryType type) const {
8484
case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break;
8585
case ENTRY_NAME(AUXV_AT_RANDOM); break;
8686
case ENTRY_NAME(AUXV_AT_HWCAP2); break;
87+
case ENTRY_NAME(AUXV_AT_HWCAP3); break;
8788
case ENTRY_NAME(AUXV_AT_EXECFN); break;
8889
case ENTRY_NAME(AUXV_AT_SYSINFO); break;
8990
case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break;

lldb/source/Plugins/Process/Utility/AuxVector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class AuxVector {
5757
AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
5858
AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes.
5959
AUXV_AT_HWCAP2 = 26, ///< Extension of AT_HWCAP.
60+
AUXV_AT_HWCAP3 = 29, ///< Extension of AT_HWCAP.
6061
AUXV_AT_EXECFN = 31, ///< Filename of executable.
6162
AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system
6263
/// calls and other nice things.

lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
using namespace lldb_private;
3030

3131
Arm64RegisterFlagsDetector::Fields
32-
Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
32+
Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
33+
uint64_t hwcap3) {
3334
(void)hwcap;
35+
(void)hwcap3;
3436

3537
if (!(hwcap2 & HWCAP2_FPMR))
3638
return {};
@@ -53,8 +55,10 @@ Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
5355

5456
Arm64RegisterFlagsDetector::Fields
5557
Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
56-
uint64_t hwcap2) {
58+
uint64_t hwcap2,
59+
uint64_t hwcap3) {
5760
(void)hwcap2;
61+
(void)hwcap3;
5862

5963
if (!(hwcap & HWCAP_GCS))
6064
return {};
@@ -67,8 +71,10 @@ Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
6771
}
6872

6973
Arm64RegisterFlagsDetector::Fields
70-
Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
74+
Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
75+
uint64_t hwcap3) {
7176
(void)hwcap;
77+
(void)hwcap3;
7278

7379
if (!(hwcap2 & HWCAP2_SME))
7480
return {};
@@ -83,9 +89,10 @@ Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
8389
}
8490

8591
Arm64RegisterFlagsDetector::Fields
86-
Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
87-
uint64_t hwcap2) {
92+
Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
93+
uint64_t hwcap3) {
8894
(void)hwcap;
95+
(void)hwcap3;
8996

9097
if (!(hwcap2 & HWCAP2_MTE))
9198
return {};
@@ -103,7 +110,10 @@ Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap,
103110
}
104111

105112
Arm64RegisterFlagsDetector::Fields
106-
Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
113+
Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
114+
uint64_t hwcap3) {
115+
(void)hwcap3;
116+
107117
static const FieldEnum rmode_enum(
108118
"rmode_enum", {{0, "RN"}, {1, "RP"}, {2, "RM"}, {3, "RZ"}});
109119

@@ -142,10 +152,12 @@ Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
142152
}
143153

144154
Arm64RegisterFlagsDetector::Fields
145-
Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
155+
Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
156+
uint64_t hwcap3) {
146157
// fpsr's contents are constant.
147158
(void)hwcap;
148159
(void)hwcap2;
160+
(void)hwcap3;
149161

150162
return {
151163
// Bits 31-28 are N/Z/C/V, only used by AArch32.
@@ -162,7 +174,10 @@ Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2) {
162174
}
163175

164176
Arm64RegisterFlagsDetector::Fields
165-
Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
177+
Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
178+
uint64_t hwcap3) {
179+
(void)hwcap3;
180+
166181
// The fields here are a combination of the Arm manual's SPSR_EL1,
167182
// plus a few changes where Linux has decided not to make use of them at all,
168183
// or at least not from userspace.
@@ -207,9 +222,10 @@ Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2) {
207222
return cpsr_fields;
208223
}
209224

210-
void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2) {
225+
void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2,
226+
uint64_t hwcap3) {
211227
for (auto &reg : m_registers)
212-
reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2));
228+
reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2, hwcap3));
213229
m_has_detected = true;
214230
}
215231

lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Arm64RegisterFlagsDetector {
4040
/// If called more than once, fields will be redetected each time from
4141
/// scratch. If the target would not have this register at all, the list of
4242
/// fields will be left empty.
43-
void DetectFields(uint64_t hwcap, uint64_t hwcap2);
43+
void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);
4444

4545
/// Add the field information of any registers named in this class,
4646
/// to the relevant RegisterInfo instances. Note that this will be done
@@ -53,15 +53,22 @@ class Arm64RegisterFlagsDetector {
5353

5454
private:
5555
using Fields = std::vector<RegisterFlags::Field>;
56-
using DetectorFn = std::function<Fields(uint64_t, uint64_t)>;
56+
using DetectorFn = std::function<Fields(uint64_t, uint64_t, uint64_t)>;
5757

58-
static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2);
59-
static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2);
60-
static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2);
61-
static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
62-
static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
63-
static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2);
64-
static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2);
58+
static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
59+
uint64_t hwcap3);
60+
static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
61+
uint64_t hwcap3);
62+
static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
63+
uint64_t hwcap3);
64+
static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
65+
uint64_t hwcap3);
66+
static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
67+
uint64_t hwcap3);
68+
static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
69+
uint64_t hwcap3);
70+
static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2,
71+
uint64_t hwcap3);
6572

6673
struct RegisterEntry {
6774
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)

lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,19 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
9696
llvm::Triple::OSType os = process->GetArchitecture().GetTriple().getOS();
9797
if ((os == llvm::Triple::Linux) || (os == llvm::Triple::FreeBSD)) {
9898
AuxVector aux_vec(process->GetAuxvData());
99-
std::optional<uint64_t> auxv_at_hwcap = aux_vec.GetAuxValue(
100-
os == llvm::Triple::FreeBSD ? AuxVector::AUXV_FREEBSD_AT_HWCAP
101-
: AuxVector::AUXV_AT_HWCAP);
99+
bool is_freebsd = os == llvm::Triple::FreeBSD;
100+
std::optional<uint64_t> auxv_at_hwcap =
101+
aux_vec.GetAuxValue(is_freebsd ? AuxVector::AUXV_FREEBSD_AT_HWCAP
102+
: AuxVector::AUXV_AT_HWCAP);
102103
std::optional<uint64_t> auxv_at_hwcap2 =
103104
aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP2);
105+
std::optional<uint64_t> auxv_at_hwcap3 =
106+
is_freebsd ? std::nullopt
107+
: aux_vec.GetAuxValue(AuxVector::AUXV_AT_HWCAP3);
104108

105109
m_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
106-
auxv_at_hwcap2.value_or(0));
110+
auxv_at_hwcap2.value_or(0),
111+
auxv_at_hwcap3.value_or(0));
107112
m_register_flags_detector.UpdateRegisterInfo(GetRegisterInfo(),
108113
GetRegisterCount());
109114
}

0 commit comments

Comments
 (0)