File indexing completed on 2024-05-12 04:39:44
0001 /* 0002 SPDX-FileCopyrightText: 2013 Vlas Puhov <vlas.puhov@mail.ru> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef _REGISTERCONTROLLER_H_ 0008 #define _REGISTERCONTROLLER_H_ 0009 0010 #include <QHash> 0011 #include <QVector> 0012 #include <QObject> 0013 #include <QStringList> 0014 #include <QString> 0015 0016 namespace KDevMI { 0017 namespace MI 0018 { 0019 struct ResultRecord; 0020 } 0021 0022 class MIDebugSession; 0023 0024 enum RegisterType {general, structured, flag, floatPoint}; 0025 0026 class GroupsName 0027 { 0028 public: 0029 QString name() const { return _name;} 0030 int index() const {return _index;} 0031 RegisterType type() const{return _type; } 0032 QString flagName() const{return _flagName;} 0033 0034 bool operator==(const GroupsName& g) const {return _name == g.name();} 0035 0036 GroupsName() {} 0037 0038 private: 0039 GroupsName(const QString& name, int idx, RegisterType type = general, const QString& flag = QString()): _name(name), _index(idx), _type(type), _flagName(flag) {} 0040 0041 private: 0042 QString _name; 0043 int _index = -1; ///Should be unique for each group for current architecture (0, 1...n). 0044 RegisterType _type = general; 0045 QString _flagName; ///Used only for flag registers. 0046 0047 friend class IRegisterController; 0048 friend struct RegistersGroup; 0049 }; 0050 0051 enum Format { 0052 Binary, 0053 Octal, 0054 Decimal, 0055 Hexadecimal, 0056 Raw, 0057 Unsigned, 0058 0059 LAST_FORMAT 0060 }; 0061 0062 enum Mode { 0063 natural, 0064 0065 v4_float, 0066 v2_double, 0067 v4_int32, 0068 v2_int64, 0069 0070 u32, 0071 u64, 0072 f32, 0073 f64, 0074 0075 LAST_MODE 0076 }; 0077 0078 struct FormatsModes { 0079 QVector<Format> formats; 0080 QVector<Mode> modes; 0081 }; 0082 0083 ///Register in format: @p name, @p value - space separated list of values 0084 struct Register { 0085 Register() {} 0086 Register(const QString& _name, const QString& _value): name(_name), value(_value) {} 0087 QString name; 0088 QString value; 0089 }; 0090 ///List of @p registers for @p groupName in @p format 0091 struct RegistersGroup { 0092 RegistersGroup() 0093 0094 {} 0095 0096 GroupsName groupName; 0097 QVector<Register> registers; 0098 Format format = Binary; ///<Current format 0099 bool flag = false; ///<true if this group is flags group. 0100 }; 0101 0102 struct FlagRegister { 0103 QStringList flags; 0104 QStringList bits; 0105 QString registerName; 0106 GroupsName groupName; 0107 }; 0108 0109 /** @brief Class for managing registers: it can retrieve, change and send registers back to the debugger.*/ 0110 class IRegisterController : public QObject 0111 { 0112 Q_OBJECT 0113 0114 public: 0115 ///Sets session @p debugSession to send commands to. 0116 void setSession(MIDebugSession* debugSession); 0117 0118 ///There'll be at least 2 groups: "General" and "Flags", also "XMM", "FPU", "Segment" for x86, x86_64 architectures. 0119 virtual QVector<GroupsName> namesOfRegisterGroups() const = 0; 0120 0121 ///Returns all supported formats for @p group (bin, dec, hex ...) 0122 QVector<Format> formats(const GroupsName& group); 0123 0124 ///Sets current format for the @p group, if format is supported. Does nothing otherwise. 0125 void setFormat(Format f, const GroupsName& group); 0126 0127 ///Returns all supported modes for @p group (i.e. how to display group: 2 int, 4 float or other number of columns) 0128 QVector<Mode> modes(const GroupsName& group); 0129 0130 ///Sets current mode for the @p group, if mode is supported. Does nothing otherwise. 0131 void setMode(Mode m, const GroupsName& group); 0132 0133 Q_SIGNALS: 0134 ///Emits @p group with updated registers. 0135 void registersChanged(const RegistersGroup& g); 0136 0137 public Q_SLOTS: 0138 ///Updates registers in @p group. If @p group is empty - updates all registers. 0139 virtual void updateRegisters(const GroupsName& group = GroupsName()); 0140 0141 ///Sends updated register's @p reg value to the debugger. 0142 virtual void setRegisterValue(const Register& reg); 0143 0144 protected: 0145 explicit IRegisterController(MIDebugSession* debugSession = nullptr, QObject* parent = nullptr); 0146 0147 ///Returns registers from the @p group, or empty registers group if @p group is invalid. 0148 virtual RegistersGroup registersFromGroup(const GroupsName& group) const = 0; 0149 0150 ///Sets value for @p register from @p group. 0151 virtual void setRegisterValueForGroup(const GroupsName& group, const Register& reg) = 0; 0152 0153 ///Returns names of all registers for @p group. 0154 virtual QStringList registerNamesForGroup(const GroupsName& group) const = 0; 0155 0156 /**Updates value for each register in the group. 0157 * @param [out] registers Registers which values should be updated. 0158 */ 0159 virtual void updateValuesForRegisters(RegistersGroup* registers) const; 0160 0161 ///Returns value for the given @p name, empty string if the name is incorrect or there is no registers yet. 0162 QString registerValue(const QString& name) const; 0163 0164 /** Sets a flag register. 0165 * @param reg register to set 0166 * @param flag flag register @p reg belongs to. 0167 */ 0168 void setFlagRegister(const Register& reg, const FlagRegister& flag); 0169 0170 ///Sets new value for register @p reg, from group @p group. 0171 void setGeneralRegister(const Register& reg, const GroupsName& group); 0172 0173 ///Sets new value for structured register(XMM, VFP quad and other) @p reg, from group @p group. 0174 void setStructuredRegister(const Register& reg, const GroupsName& group); 0175 0176 ///Updates values in @p flagsGroup for @p flagRegister. 0177 void updateFlagValues(RegistersGroup* flagsGroup, const FlagRegister& flagRegister) const; 0178 0179 ///Returns group that given register belongs to. 0180 GroupsName groupForRegisterName(const QString& name) const; 0181 0182 ///Initializes registers, that is gets names of all available registers. Returns true is succeed. 0183 bool initializeRegisters(); 0184 0185 GroupsName createGroupName(const QString& name, int idx, RegisterType t = general, const QString& flag = QString()) const; 0186 0187 ///Returns register's number for @p name. 0188 QString numberForName(const QString& name) const; 0189 0190 public: 0191 ~IRegisterController() override; 0192 0193 private : 0194 ///Handles initialization of register's names. 0195 void registerNamesHandler(const MI::ResultRecord& r); 0196 0197 ///Parses new values for general registers from @p r and updates it in m_registers. 0198 ///Emits registersChanged signal. 0199 void generalRegistersHandler(const MI::ResultRecord& r); 0200 0201 ///Parses new values for structured registers from @p r and updates it in m_registers. 0202 ///Emits registersChanged signal. 0203 virtual void structuredRegistersHandler(const MI::ResultRecord& r); 0204 0205 private: 0206 0207 ///Groups that should be updated(emitted @p registersInGroupChanged signal), if empty - all. 0208 QVector<GroupsName> m_pendingGroups; 0209 0210 protected: 0211 ///Register names as it sees debugger (in format: number, name). 0212 QVector<QString > m_rawRegisterNames; 0213 0214 ///Registers in format: name, value 0215 QHash<QString, QString > m_registers; 0216 0217 ///Supported formats and modes for each register's group. First format/mode is current. 0218 QVector<FormatsModes > m_formatsModes; 0219 0220 ///Current debug session; 0221 MIDebugSession* m_debugSession; 0222 }; 0223 0224 } // end of namespace KDevMI 0225 0226 Q_DECLARE_TYPEINFO(KDevMI::Register, Q_MOVABLE_TYPE); 0227 Q_DECLARE_TYPEINFO(KDevMI::RegistersGroup, Q_MOVABLE_TYPE); 0228 Q_DECLARE_TYPEINFO(KDevMI::FlagRegister, Q_MOVABLE_TYPE); 0229 Q_DECLARE_TYPEINFO(KDevMI::GroupsName, Q_MOVABLE_TYPE); 0230 Q_DECLARE_TYPEINFO(KDevMI::FormatsModes, Q_MOVABLE_TYPE); 0231 0232 #endif