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 16 namespace lldb_private { 17 18 struct 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. 36 class Arm64RegisterFlagsDetector { 37 public: 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 54 private: 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