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
12#include "lldb/Target/RegisterFlags.h"
13#include "llvm/ADT/StringRef.h"
14#include <functional>
15
16namespace lldb_private {
17
18struct RegisterInfo;
19
20/// This class manages the storage and detection of register field information.
21/// The same register may have different fields on different CPUs. This class
22/// abstracts out the field detection process so we can use it on live processes
23/// and core files.
24///
25/// The way to use this class is:
26/// * Make an instance somewhere that will last as long as the debug session
27/// (because your final register info will point to this instance).
28/// * Read hardware capabilities from a core note, binary, prctl, etc.
29/// * Pass those to DetectFields.
30/// * Call UpdateRegisterInfo with your RegisterInfo to add pointers
31/// to the detected fields for all registers listed in this class.
32///
33/// This must be done in that order, and you should ensure that if multiple
34/// threads will reference the information, a mutex is used to make sure only
35/// one calls DetectFields.
36class Arm64RegisterFlagsDetector {
37public:
38 /// For the registers listed in this class, detect which fields are
39 /// present. Must be called before UpdateRegisterInfos.
40 /// If called more than once, fields will be redetected each time from
41 /// scratch. If the target would not have this register at all, the list of
42 /// fields will be left empty.
43 void DetectFields(uint64_t hwcap, uint64_t hwcap2);
44
45 /// Add the field information of any registers named in this class,
46 /// to the relevant RegisterInfo instances. Note that this will be done
47 /// with a pointer to the instance of this class that you call this on, so
48 /// the lifetime of that instance must be at least that of the register info.
49 void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs);
50
51 /// Returns true if field detection has been run at least once.
52 bool HasDetected() const { return m_has_detected; }
53
54private:
55 using Fields = std::vector<RegisterFlags::Field>;
56 using DetectorFn = std::function<Fields(uint64_t, uint64_t)>;
57
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);
65
66 struct RegisterEntry {
67 RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
68 : m_name(name), m_flags(std::string(name) + "_flags", size, {}),
69 m_detector(detector) {}
70
71 llvm::StringRef m_name;
72 RegisterFlags m_flags;
73 DetectorFn m_detector;
74 } m_registers[8] = {
75 RegisterEntry("cpsr", 4, DetectCPSRFields),
76 RegisterEntry("fpsr", 4, DetectFPSRFields),
77 RegisterEntry("fpcr", 4, DetectFPCRFields),
78 RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
79 RegisterEntry("svcr", 8, DetectSVCRFields),
80 RegisterEntry("fpmr", 8, DetectFPMRFields),
81 RegisterEntry("gcs_features_enabled", 8, DetectGCSFeatureFields),
82 RegisterEntry("gcs_features_locked", 8, DetectGCSFeatureFields),
83 };
84
85 // Becomes true once field detection has been run for all registers.
86 bool m_has_detected = false;
87};
88
89} // namespace lldb_private
90
91#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H
92

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