LLDB mainline
RegisterFlagsDetector_arm64.h
Go to the documentation of this file.
1//===-- RegisterFlagsDetector_arm64.h ---------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H
10#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H
11
14#include "llvm/ADT/StringRef.h"
15#include <functional>
16
17namespace lldb_private {
18
19struct RegisterInfo;
20
21/// This class manages the storage and detection of register field information.
22/// The same register may have different fields on different CPUs. This class
23/// abstracts out the field detection process so we can use it on live processes
24/// and core files.
25///
26/// The way to use this class is:
27/// * Make an instance somewhere that will last as long as the debug session
28/// (because your final register info will point to this instance).
29/// * Read hardware capabilities from a core note, binary, prctl, etc.
30/// * Pass those to DetectFields.
31/// * Call UpdateRegisterInfo with your RegisterInfo to add pointers
32/// to the detected fields for all registers listed in this class.
33///
34/// This must be done in that order, and you should ensure that if multiple
35/// threads will reference the information, a mutex is used to make sure only
36/// one calls DetectFields.
38public:
39 /// For the registers listed in this class, detect which fields are
40 /// present. Must be called before UpdateRegisterInfos.
41 /// If called more than once, fields will be redetected each time from
42 /// scratch. If the target would not have this register at all, the list of
43 /// fields will be left empty.
44 void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);
45
46 /// Add the field information of any registers named in this class,
47 /// to the relevant RegisterInfo instances. Note that this will be done
48 /// with a pointer to the instance of this class that you call this on, so
49 /// the lifetime of that instance must be at least that of the register info.
50 void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs);
51
52 /// Returns true if field detection has been run at least once.
53 bool HasDetected() const { return m_has_detected; }
54
55private:
56 using Fields = std::vector<RegisterFlags::Field>;
57 using DetectorFn = std::function<Fields(uint64_t, uint64_t, uint64_t)>;
58
59 static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2,
60 uint64_t hwcap3);
61 static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2,
62 uint64_t hwcap3);
63 static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2,
64 uint64_t hwcap3);
65 static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2,
66 uint64_t hwcap3);
67 static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2,
68 uint64_t hwcap3);
69 static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2,
70 uint64_t hwcap3);
71 static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2,
72 uint64_t hwcap3);
73 static Fields DetectPOREL0Fields(uint64_t hwcap, uint64_t hwcap2,
74 uint64_t hwcap3);
75
77 RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
78 : m_name(name), m_flags(std::string(name) + "_flags", size, {}),
79 m_detector(detector) {}
80
81 llvm::StringRef m_name;
84 } m_registers[9] = {
88 RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
91 RegisterEntry("gcs_features_enabled", 8, DetectGCSFeatureFields),
92 RegisterEntry("gcs_features_locked", 8, DetectGCSFeatureFields),
93 RegisterEntry("por_el0", 8, DetectPOREL0Fields),
94 };
95
96 // Becomes true once field detection has been run for all registers.
97 bool m_has_detected = false;
98};
99
100} // namespace lldb_private
101
102#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H
This class manages the storage and detection of register field information.
static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
For the registers listed in this class, detect which fields are present.
void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs)
Add the field information of any registers named in this class, to the relevant RegisterInfo instance...
struct lldb_private::Arm64RegisterFlagsDetector::RegisterEntry m_registers[9]
static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
std::function< Fields(uint64_t, uint64_t, uint64_t)> DetectorFn
static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
bool HasDetected() const
Returns true if field detection has been run at least once.
static Fields DetectPOREL0Fields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
A class that represents a running process on the host machine.
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
Every register is described in detail including its name, alternate name (optional),...