brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · aec2bf9 Raw
99 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H10#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H11 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 class22/// abstracts out the field detection process so we can use it on live processes23/// 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 session27///   (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 pointers31///   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 multiple34/// threads will reference the information, a mutex is used to make sure only35/// one calls DetectFields.36class Arm64RegisterFlagsDetector {37public:38  /// For the registers listed in this class, detect which fields are39  /// present. Must be called before UpdateRegisterInfos.40  /// If called more than once, fields will be redetected each time from41  /// scratch. If the target would not have this register at all, the list of42  /// fields will be left empty.43  void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3);44 45  /// Add the field information of any registers named in this class,46  /// to the relevant RegisterInfo instances. Note that this will be done47  /// with a pointer to the instance of this class that you call this on, so48  /// 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, uint64_t)>;57 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);72 73  struct RegisterEntry {74    RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)75        : m_name(name), m_flags(std::string(name) + "_flags", size, {}),76          m_detector(detector) {}77 78    llvm::StringRef m_name;79    RegisterFlags m_flags;80    DetectorFn m_detector;81  } m_registers[8] = {82      RegisterEntry("cpsr", 4, DetectCPSRFields),83      RegisterEntry("fpsr", 4, DetectFPSRFields),84      RegisterEntry("fpcr", 4, DetectFPCRFields),85      RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),86      RegisterEntry("svcr", 8, DetectSVCRFields),87      RegisterEntry("fpmr", 8, DetectFPMRFields),88      RegisterEntry("gcs_features_enabled", 8, DetectGCSFeatureFields),89      RegisterEntry("gcs_features_locked", 8, DetectGCSFeatureFields),90  };91 92  // Becomes true once field detection has been run for all registers.93  bool m_has_detected = false;94};95 96} // namespace lldb_private97 98#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERFLAGSDETECTOR_ARM64_H99