Author: David Spickett
Date: 2026-08-07T10:47:15+01:00
New Revision: b3a4504bd99bbfb9d6d3b0b87af835ccef8bef42

URL: 
https://github.com/llvm/llvm-project/commit/b3a4504bd99bbfb9d6d3b0b87af835ccef8bef42
DIFF: 
https://github.com/llvm/llvm-project/commit/b3a4504bd99bbfb9d6d3b0b87af835ccef8bef42.diff

LOG: [lldb] Make RegisterFlagsDetector into RegisterTypesDetector (#213892)

In future it may be generating things other than flags. Functionality
is the same, but the interface changes to use RegisterType.

Added: 
    lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.cpp
    lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.h

Modified: 
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
    lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
    lldb/source/Plugins/Process/Utility/CMakeLists.txt
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h

Removed: 
    lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
    lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h


################################################################################
diff  --git 
a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp 
b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
index 74c55224fed49..1f2e0d5904148 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -16,8 +16,8 @@
 
 #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"
+#include "Plugins/Process/Utility/RegisterTypeDetector_arm64.h"
 
 // clang-format off
 #include <sys/param.h>
@@ -33,16 +33,16 @@ using namespace lldb_private::process_freebsd;
 // 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;
+static std::mutex g_register_type_detector_mutex;
+static Arm64RegisterTypeDetector g_register_type_detector;
 
 NativeRegisterContextFreeBSD *
 NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
     const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {
-  std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
-  if (!g_register_flags_detector.HasDetected()) {
+  std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
+  if (!g_register_type_detector.HasDetected()) {
     NativeProcessFreeBSD &process = native_thread.GetProcess();
-    g_register_flags_detector.DetectFields(
+    g_register_type_detector.DetectTypes(
         process.GetAuxValue(AuxVector::AUXV_FREEBSD_AT_HWCAP).value_or(0),
         process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2).value_or(0),
         /*hwcap3=*/0);
@@ -56,7 +56,7 @@ 
NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
     : NativeRegisterContextRegisterInfo(
           native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0)),
       m_read_dbreg(false) {
-  g_register_flags_detector.UpdateRegisterInfo(
+  g_register_type_detector.UpdateRegisterInfo(
       GetRegisterInfoInterface().GetRegisterInfo(),
       GetRegisterInfoInterface().GetRegisterCount());
 }

diff  --git 
a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp 
b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 82d6f8658c30b..3c279cd9b1029 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -24,8 +24,8 @@
 #include "Plugins/Process/Linux/Procfs.h"
 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
 #include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
-#include "Plugins/Process/Utility/RegisterFlagsDetector_arm64.h"
 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/RegisterTypeDetector_arm64.h"
 
 #include "llvm/BinaryFormat/ELF.h"
 
@@ -63,8 +63,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_detector_mutex;
-static Arm64RegisterFlagsDetector g_register_flags_detector;
+static std::mutex g_register_type_detector_mutex;
+static Arm64RegisterTypeDetector g_register_type_detector;
 
 std::unique_ptr<NativeRegisterContextLinux>
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
@@ -144,11 +144,11 @@ 
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
 
     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_hwcap3.value_or(0));
+    std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
+    if (!g_register_type_detector.HasDetected())
+      g_register_type_detector.DetectTypes(auxv_at_hwcap.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);
@@ -172,7 +172,7 @@ 
NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
     : NativeRegisterContextRegisterInfo(native_thread,
                                         register_info_up.release()),
       NativeRegisterContextLinux(native_thread) {
-  g_register_flags_detector.UpdateRegisterInfo(
+  g_register_type_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 3652a0cfb530f..90cf4d20bbc07 100644
--- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -52,7 +52,7 @@ add_lldb_library(lldbPluginProcessUtility
   RegisterContextThreadMemory.cpp
   RegisterContextWindows_i386.cpp
   RegisterContextWindows_x86_64.cpp
-  RegisterFlagsDetector_arm64.cpp
+  RegisterTypeDetector_arm64.cpp
   RegisterInfos_x86_64_with_base_shared.cpp
   RegisterInfoPOSIX_arm.cpp
   RegisterInfoPOSIX_arm64.cpp

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h 
b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
deleted file mode 100644
index 217fd41922fc5..0000000000000
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//===-- 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.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H
-
-#include "lldb/Utility/RegisterTypeFlags.h"
-#include "llvm/ADT/StringRef.h"
-#include <functional>
-
-namespace lldb_private {
-
-struct RegisterInfo;
-
-/// This class manages the storage and detection of register field information.
-/// The same register may have 
diff erent fields on 
diff erent CPUs. This class
-/// abstracts out the field detection process so we can use it on live 
processes
-/// and core files.
-///
-/// 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.
-/// * Pass those to DetectFields.
-/// * Call UpdateRegisterInfo with your RegisterInfo to add pointers
-///   to the detected fields for all registers listed in this class.
-///
-/// 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 Arm64RegisterFlagsDetector {
-public:
-  /// For the registers listed in this class, detect which fields are
-  /// present. Must be called before UpdateRegisterInfos.
-  /// 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, 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
-  /// with a pointer to the instance of this class that you call this on, so
-  /// the lifetime of that instance must be at least that of the register info.
-  void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs);
-
-  /// Returns true if field detection has been run at least once.
-  bool HasDetected() const { return m_has_detected; }
-
-private:
-  using Fields = std::vector<RegisterTypeFlags::Field>;
-  using DetectorFn = std::function<Fields(uint64_t, uint64_t, uint64_t)>;
-
-  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);
-  static Fields DetectPOREL0Fields(uint64_t hwcap, uint64_t hwcap2,
-                                   uint64_t hwcap3);
-
-  struct RegisterEntry {
-    RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
-        : m_name(name), m_flags(std::string(name) + "_flags", size, {}),
-          m_detector(detector) {}
-
-    llvm::StringRef m_name;
-    RegisterTypeFlags m_flags;
-    DetectorFn m_detector;
-  } m_registers[9] = {
-      RegisterEntry("cpsr", 4, DetectCPSRFields),
-      RegisterEntry("fpsr", 4, DetectFPSRFields),
-      RegisterEntry("fpcr", 4, DetectFPCRFields),
-      RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
-      RegisterEntry("svcr", 8, DetectSVCRFields),
-      RegisterEntry("fpmr", 8, DetectFPMRFields),
-      RegisterEntry("gcs_features_enabled", 8, DetectGCSFeatureFields),
-      RegisterEntry("gcs_features_locked", 8, DetectGCSFeatureFields),
-      RegisterEntry("por_el0", 8, DetectPOREL0Fields),
-  };
-
-  // Becomes true once field detection has been run for all registers.
-  bool m_has_detected = false;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H

diff  --git 
a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp 
b/lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.cpp
similarity index 59%
rename from lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
rename to lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.cpp
index 5c78a690167d0..8e7ddca73b27b 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterFlagsDetector_arm64.cpp 
-----------------------------------===//
+//===-- RegisterTypeDetector_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,9 +6,8 @@
 //
 
//===----------------------------------------------------------------------===//
 
-#include "RegisterFlagsDetector_arm64.h"
-#include "lldb/Utility/RegisterInfo.h"
-#include "lldb/lldb-private-types.h"
+#include "RegisterTypeDetector_arm64.h"
+#include "lldb/Utility/RegisterTypeFlags.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.
@@ -32,9 +31,9 @@
 
 using namespace lldb_private;
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectPOREL0Fields(uint64_t hwcap, uint64_t hwcap2,
-                                               uint64_t hwcap3) {
+const RegisterType *
+Arm64RegisterTypeDetector::DetectPOREL0Type(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3) {
   (void)hwcap;
   (void)hwcap3;
 
@@ -53,29 +52,33 @@ Arm64RegisterFlagsDetector::DetectPOREL0Fields(uint64_t 
hwcap, uint64_t hwcap2,
                                {0b0111, "Read, Write, Execute"},
                            });
 
-  return {
-      {"Perm15", 60, 63, &por_el0_perm_enum},
-      {"Perm14", 56, 59, &por_el0_perm_enum},
-      {"Perm13", 52, 55, &por_el0_perm_enum},
-      {"Perm12", 48, 51, &por_el0_perm_enum},
-      {"Perm11", 44, 47, &por_el0_perm_enum},
-      {"Perm10", 40, 43, &por_el0_perm_enum},
-      {"Perm9", 36, 39, &por_el0_perm_enum},
-      {"Perm8", 32, 35, &por_el0_perm_enum},
-      {"Perm7", 28, 31, &por_el0_perm_enum},
-      {"Perm6", 24, 27, &por_el0_perm_enum},
-      {"Perm5", 20, 23, &por_el0_perm_enum},
-      {"Perm4", 16, 19, &por_el0_perm_enum},
-      {"Perm3", 12, 15, &por_el0_perm_enum},
-      {"Perm2", 8, 11, &por_el0_perm_enum},
-      {"Perm1", 4, 7, &por_el0_perm_enum},
-      {"Perm0", 0, 3, &por_el0_perm_enum},
-  };
+  static const RegisterTypeFlags por_el0_flags(
+      "por_el0_flags", 8,
+      {
+          {"Perm15", 60, 63, &por_el0_perm_enum},
+          {"Perm14", 56, 59, &por_el0_perm_enum},
+          {"Perm13", 52, 55, &por_el0_perm_enum},
+          {"Perm12", 48, 51, &por_el0_perm_enum},
+          {"Perm11", 44, 47, &por_el0_perm_enum},
+          {"Perm10", 40, 43, &por_el0_perm_enum},
+          {"Perm9", 36, 39, &por_el0_perm_enum},
+          {"Perm8", 32, 35, &por_el0_perm_enum},
+          {"Perm7", 28, 31, &por_el0_perm_enum},
+          {"Perm6", 24, 27, &por_el0_perm_enum},
+          {"Perm5", 20, 23, &por_el0_perm_enum},
+          {"Perm4", 16, 19, &por_el0_perm_enum},
+          {"Perm3", 12, 15, &por_el0_perm_enum},
+          {"Perm2", 8, 11, &por_el0_perm_enum},
+          {"Perm1", 4, 7, &por_el0_perm_enum},
+          {"Perm0", 0, 3, &por_el0_perm_enum},
+      });
+
+  return &por_el0_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
-                                             uint64_t hwcap3) {
+const RegisterType *Arm64RegisterTypeDetector::DetectFPMRType(uint64_t hwcap,
+                                                              uint64_t hwcap2,
+                                                              uint64_t hwcap3) 
{
   (void)hwcap;
   (void)hwcap3;
 
@@ -87,60 +90,59 @@ Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t 
hwcap, uint64_t hwcap2,
                                                     {0, "FP8_E5M2"},
                                                     {1, "FP8_E4M3"},
                                                 });
-  return {
-      {"LSCALE2", 32, 37},
-      {"NSCALE", 24, 31},
-      {"LSCALE", 16, 22},
-      {"OSC", 15},
-      {"OSM", 14},
-      {"F8D", 6, 8, &fp8_format_enum},
-      {"F8S2", 3, 5, &fp8_format_enum},
-      {"F8S1", 0, 2, &fp8_format_enum},
-  };
+
+  static const RegisterTypeFlags fpmr_flags("fpmr_flags", 8,
+                                            {{"LSCALE2", 32, 37},
+                                             {"NSCALE", 24, 31},
+                                             {"LSCALE", 16, 22},
+                                             {"OSC", 15},
+                                             {"OSM", 14},
+                                             {"F8D", 6, 8, &fp8_format_enum},
+                                             {"F8S2", 3, 5, &fp8_format_enum},
+                                             {"F8S1", 0, 2, 
&fp8_format_enum}});
+
+  return &fpmr_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
-                                                   uint64_t hwcap2,
-                                                   uint64_t hwcap3) {
+const RegisterType *Arm64RegisterTypeDetector::DetectGCSFeaturesType(
+    uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3) {
   (void)hwcap2;
   (void)hwcap3;
 
   if (!(hwcap & HWCAP_GCS))
     return {};
 
-  return {
-      {"PUSH", 2},
-      {"WRITE", 1},
-      {"ENABLE", 0},
-  };
+  static const RegisterTypeFlags gcs_features_flags(
+      "gcs_features_flags", 8, {{"PUSH", 2}, {"WRITE", 1}, {"ENABLE", 0}});
+
+  return &gcs_features_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
-                                             uint64_t hwcap3) {
+const RegisterType *Arm64RegisterTypeDetector::DetectSVCRType(uint64_t hwcap,
+                                                              uint64_t hwcap2,
+                                                              uint64_t hwcap3) 
{
   (void)hwcap;
   (void)hwcap3;
 
   if (!(hwcap2 & HWCAP2_SME))
-    return {};
+    return nullptr;
 
   // Represents the pseudo register that lldb-server builds, which itself
   // matches the architectural register SCVR. The fields match SVCR in the Arm
   // manual.
-  return {
-      {"ZA", 1},
-      {"SM", 0},
-  };
+  static const RegisterTypeFlags svcr_flags("svcr_flags", 8,
+                                            {{"ZA", 1}, {"SM", 0}});
+
+  return &svcr_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, uint64_t 
hwcap2,
-                                                uint64_t hwcap3) {
+const RegisterType *
+Arm64RegisterTypeDetector::DetectMTECtrlType(uint64_t hwcap, uint64_t hwcap2,
+                                             uint64_t hwcap3) {
   (void)hwcap;
 
   if (!(hwcap2 & HWCAP2_MTE))
-    return {};
+    return nullptr;
 
   // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed
   // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines
@@ -161,16 +163,19 @@ Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t 
hwcap, uint64_t hwcap2,
        {"TCF", 1, 2, &tcf_enum},
        {"TAGGED_ADDR_ENABLE", 0}});
 
-  return fields;
+  static const RegisterTypeFlags mte_ctrl_flags("mte_ctrl_flags", 8, fields);
+
+  return &mte_ctrl_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
-                                             uint64_t hwcap3) {
+const RegisterType *Arm64RegisterTypeDetector::DetectFPCRType(uint64_t hwcap,
+                                                              uint64_t hwcap2,
+                                                              uint64_t hwcap3) 
{
   (void)hwcap3;
 
   static const RegisterTypeEnum rmode_enum(
       "rmode_enum", {{0, "RN"}, {1, "RP"}, {2, "RM"}, {3, "RZ"}});
+  static RegisterTypeFlags fpcr_flags("fpcr_flags", 4, {});
 
   std::vector<RegisterTypeFlags::Field> fpcr_fields{
       {"AHP", 26},
@@ -206,39 +211,46 @@ Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t 
hwcap, uint64_t hwcap2,
     fpcr_fields.push_back({"FIZ", 0});
   }
 
-  return fpcr_fields;
+  fpcr_flags.SetFields(fpcr_fields);
+
+  return &fpcr_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
-                                             uint64_t hwcap3) {
+const RegisterType *Arm64RegisterTypeDetector::DetectFPSRType(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.
-      {"QC", 27},
-      // Bits 26-8 reserved.
-      {"IDC", 7},
-      // Bits 6-5 reserved.
-      {"IXC", 4},
-      {"UFC", 3},
-      {"OFC", 2},
-      {"DZC", 1},
-      {"IOC", 0},
-  };
+  static const RegisterTypeFlags fpsr_flags(
+      "fpsr_flags", 4,
+      {
+          // Bits 31-28 are N/Z/C/V, only used by AArch32.
+          {"QC", 27},
+          // Bits 26-8 reserved.
+          {"IDC", 7},
+          // Bits 6-5 reserved.
+          {"IXC", 4},
+          {"UFC", 3},
+          {"OFC", 2},
+          {"DZC", 1},
+          {"IOC", 0},
+      });
+
+  return &fpsr_flags;
 }
 
-Arm64RegisterFlagsDetector::Fields
-Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
-                                             uint64_t hwcap3) {
+const RegisterType *Arm64RegisterTypeDetector::DetectCPSRType(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.
+  static RegisterTypeFlags cpsr_flags("cpsr_flags", 4, {});
 
   // Status bits that are always present.
   std::vector<RegisterTypeFlags::Field> cpsr_fields{
@@ -280,31 +292,33 @@ Arm64RegisterFlagsDetector::DetectCPSRFields(uint64_t 
hwcap, uint64_t hwcap2,
   // Bit 1 is unused and expected to be 0.
   cpsr_fields.push_back({"SP", 0});
 
-  return cpsr_fields;
+  cpsr_flags.SetFields(cpsr_fields);
+
+  return &cpsr_flags;
 }
 
-void Arm64RegisterFlagsDetector::DetectFields(uint64_t hwcap, uint64_t hwcap2,
-                                              uint64_t hwcap3) {
+void Arm64RegisterTypeDetector::DetectTypes(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3) {
   for (auto &reg : m_registers)
-    reg.m_flags.SetFields(reg.m_detector(hwcap, hwcap2, hwcap3));
+    reg.m_type = reg.m_detector(hwcap, hwcap2, hwcap3);
   m_has_detected = true;
 }
 
-void Arm64RegisterFlagsDetector::UpdateRegisterInfo(
-    const RegisterInfo *reg_info, uint32_t num_regs) {
+void Arm64RegisterTypeDetector::UpdateRegisterInfo(const RegisterInfo 
*reg_info,
+                                                   uint32_t num_regs) {
   assert(m_has_detected &&
-         "Must call DetectFields before updating register info.");
+         "Must call DetectTypes before updating register info.");
 
   // Register names will not be duplicated, so we do not want to compare 
against
   // one if it has already been found. Each time we find one, we erase it from
   // this list.
-  std::vector<std::pair<llvm::StringRef, const RegisterTypeFlags *>>
+  std::vector<std::pair<llvm::StringRef, const RegisterType *>>
       search_registers;
   for (const auto &reg : m_registers) {
     // It is possible that a register is all extension dependent fields, and
     // none of them are present.
-    if (reg.m_flags.GetFields().size())
-      search_registers.push_back({reg.m_name, &reg.m_flags});
+    if (reg.m_type)
+      search_registers.push_back({reg.m_name, reg.m_type});
   }
 
   // Walk register information while there are registers we know need

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.h 
b/lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.h
new file mode 100644
index 0000000000000..18c2f58bd4d4e
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterTypeDetector_arm64.h
@@ -0,0 +1,99 @@
+//===-- RegisterTypeDetector_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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERTYPEDETECTOR_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERTYPEDETECTOR_ARM64_H
+
+#include "lldb/Utility/RegisterInfo.h"
+#include "lldb/Utility/RegisterType.h"
+#include "llvm/ADT/StringRef.h"
+#include <functional>
+
+namespace lldb_private {
+
+/// This class manages the storage and detection of register type information.
+/// The same register may have 
diff erent fields on 
diff erent CPUs. This class
+/// abstracts out the field detection process so we can use it on live 
processes
+/// and core files.
+///
+/// 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.
+/// * Pass those to DetectTypes.
+/// * Call UpdateRegisterInfo with your RegisterInfo to add pointers
+///   to the detected types for all registers listed in this class.
+///
+/// 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 DetectTypes.
+class Arm64RegisterTypeDetector {
+public:
+  /// For the registers listed in this class, detect which fields are
+  /// present and build types for those. Must be called before
+  /// UpdateRegisterInfos. If called more than once, fields will be redetected
+  /// each time from scratch. If the target would not have this register at 
all,
+  /// no type is produced.
+  void DetectTypes(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);
+
+  /// Add the type information of any registers named in this class,
+  /// to the relevant RegisterInfo instances. Note that this will be done
+  /// with a pointer to the instance of this class that you call this on, so
+  /// the lifetime of that instance must be at least that of the register info.
+  void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs);
+
+  /// Returns true if field detection has been run at least once.
+  bool HasDetected() const { return m_has_detected; }
+
+private:
+  using DetectorFn =
+      std::function<const RegisterType *(uint64_t, uint64_t, uint64_t)>;
+
+  static const RegisterType *DetectCPSRType(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3);
+  static const RegisterType *DetectFPSRType(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3);
+  static const RegisterType *DetectFPCRType(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3);
+  static const RegisterType *DetectMTECtrlType(uint64_t hwcap, uint64_t hwcap2,
+                                               uint64_t hwcap3);
+  static const RegisterType *DetectSVCRType(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3);
+  static const RegisterType *DetectFPMRType(uint64_t hwcap, uint64_t hwcap2,
+                                            uint64_t hwcap3);
+  static const RegisterType *
+  DetectGCSFeaturesType(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);
+  static const RegisterType *DetectPOREL0Type(uint64_t hwcap, uint64_t hwcap2,
+                                              uint64_t hwcap3);
+
+  struct RegisterEntry {
+    RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
+        : m_name(name), m_type(nullptr), m_detector(detector) {}
+
+    llvm::StringRef m_name;
+    const RegisterType *m_type;
+    DetectorFn m_detector;
+  } m_registers[9] = {
+      RegisterEntry("cpsr", 4, DetectCPSRType),
+      RegisterEntry("fpsr", 4, DetectFPSRType),
+      RegisterEntry("fpcr", 4, DetectFPCRType),
+      RegisterEntry("mte_ctrl", 8, DetectMTECtrlType),
+      RegisterEntry("svcr", 8, DetectSVCRType),
+      RegisterEntry("fpmr", 8, DetectFPMRType),
+      RegisterEntry("gcs_features_enabled", 8, DetectGCSFeaturesType),
+      RegisterEntry("gcs_features_locked", 8, DetectGCSFeaturesType),
+      RegisterEntry("por_el0", 8, DetectPOREL0Type),
+  };
+
+  // Becomes true once field detection has been run for all registers.
+  bool m_has_detected = false;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERTYPEDETECTOR_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 feeed4a9f0ac3..837cb30798fe1 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/RegisterFlagsDetector_arm64.h"
+#include "Plugins/Process/Utility/RegisterTypeDetector_arm64.h"
 #include "Plugins/Process/elf-core/ProcessElfCore.h"
 #include "Plugins/Process/elf-core/RegisterUtilities.h"
 #include "lldb/Target/Thread.h"
@@ -113,11 +113,11 @@ 
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
         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_hwcap3.value_or(0));
-    m_register_flags_detector.UpdateRegisterInfo(GetRegisterInfo(),
-                                                 GetRegisterCount());
+    m_register_type_detector.DetectTypes(auxv_at_hwcap.value_or(0),
+                                         auxv_at_hwcap2.value_or(0),
+                                         auxv_at_hwcap3.value_or(0));
+    m_register_type_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 f6d6c522d836a..9d9a2da2bc1b9 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/RegisterFlagsDetector_arm64.h"
+#include "Plugins/Process/Utility/RegisterTypeDetector_arm64.h"
 
 #include "Plugins/Process/elf-core/RegisterUtilities.h"
 #include "lldb/Utility/DataBufferHeap.h"
@@ -78,7 +78,7 @@ class RegisterContextCorePOSIX_arm64 : public 
RegisterContextPOSIX_arm64 {
 
   struct sme_pseudo_regs m_sme_pseudo_regs;
 
-  lldb_private::Arm64RegisterFlagsDetector m_register_flags_detector;
+  lldb_private::Arm64RegisterTypeDetector m_register_type_detector;
 
   const uint8_t *GetSVEBuffer(uint64_t offset = 0);
 


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to