| /* Copyright (C) 2006-2024 Free Software Foundation, Inc. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| #ifndef COMMON_TDESC_H |
| #define COMMON_TDESC_H |
| |
| struct tdesc_feature; |
| struct tdesc_type; |
| struct tdesc_type_builtin; |
| struct tdesc_type_vector; |
| struct tdesc_type_with_fields; |
| struct tdesc_reg; |
| struct target_desc; |
| |
| /* The interface to visit different elements of target description. */ |
| |
| class tdesc_element_visitor |
| { |
| public: |
| virtual void visit_pre (const target_desc *e) |
| {} |
| |
| virtual void visit_post (const target_desc *e) |
| {} |
| |
| virtual void visit_pre (const tdesc_feature *e) |
| {} |
| |
| virtual void visit_post (const tdesc_feature *e) |
| {} |
| |
| virtual void visit (const tdesc_type_builtin *e) |
| {} |
| |
| virtual void visit (const tdesc_type_vector *e) |
| {} |
| |
| virtual void visit (const tdesc_type_with_fields *e) |
| {} |
| |
| virtual void visit (const tdesc_reg *e) |
| {} |
| }; |
| |
| class tdesc_element |
| { |
| public: |
| virtual void accept (tdesc_element_visitor &v) const = 0; |
| }; |
| |
| /* An individual register from a target description. */ |
| |
| struct tdesc_reg : tdesc_element |
| { |
| tdesc_reg (struct tdesc_feature *feature, const std::string &name_, |
| int regnum, int save_restore_, const char *group_, |
| int bitsize_, const char *type_); |
| |
| virtual ~tdesc_reg () = default; |
| |
| DISABLE_COPY_AND_ASSIGN (tdesc_reg); |
| |
| /* The name of this register. In standard features, it may be |
| recognized by the architecture support code, or it may be purely |
| for the user. */ |
| std::string name; |
| |
| /* The register number used by this target to refer to this |
| register. This is used for remote p/P packets and to determine |
| the ordering of registers in the remote g/G packets. */ |
| long target_regnum; |
| |
| /* If this flag is set, GDB should save and restore this register |
| around calls to an inferior function. */ |
| int save_restore; |
| |
| /* The name of the register group containing this register, or empty |
| if the group should be automatically determined from the |
| register's type. If this is "general", "float", or "vector", the |
| corresponding "info" command should display this register's |
| value. It can be an arbitrary string, but should be limited to |
| alphanumeric characters and internal hyphens. Currently other |
| strings are ignored (treated as empty). */ |
| std::string group; |
| |
| /* The size of the register, in bits. */ |
| int bitsize; |
| |
| /* The type of the register. This string corresponds to either |
| a named type from the target description or a predefined |
| type from GDB. */ |
| std::string type; |
| |
| /* The target-described type corresponding to TYPE, if found. */ |
| struct tdesc_type *tdesc_type; |
| |
| void accept (tdesc_element_visitor &v) const override |
| { |
| v.visit (this); |
| } |
| |
| bool operator== (const tdesc_reg &other) const |
| { |
| return (name == other.name |
| && target_regnum == other.target_regnum |
| && save_restore == other.save_restore |
| && bitsize == other.bitsize |
| && group == other.group |
| && type == other.type); |
| } |
| |
| bool operator!= (const tdesc_reg &other) const |
| { |
| return !(*this == other); |
| } |
| }; |
| |
| typedef std::unique_ptr<tdesc_reg> tdesc_reg_up; |
| |
| /* Declaration of a structure that holds information about one |
| "compatibility" entry within a target description. */ |
| |
| struct tdesc_compatible_info; |
| |
| /* A pointer to a single piece of compatibility information. */ |
| |
| typedef std::unique_ptr<tdesc_compatible_info> tdesc_compatible_info_up; |
| |
| /* Return a vector of compatibility information pointers from the target |
| description TARGET_DESC. */ |
| |
| const std::vector<tdesc_compatible_info_up> &tdesc_compatible_info_list |
| (const target_desc *target_desc); |
| |
| /* Return the architecture name from a compatibility information |
| COMPATIBLE. */ |
| |
| const char *tdesc_compatible_info_arch_name |
| (const tdesc_compatible_info_up &compatible); |
| |
| enum tdesc_type_kind |
| { |
| /* Predefined types. */ |
| TDESC_TYPE_BOOL, |
| TDESC_TYPE_INT8, |
| TDESC_TYPE_INT16, |
| TDESC_TYPE_INT32, |
| TDESC_TYPE_INT64, |
| TDESC_TYPE_INT128, |
| TDESC_TYPE_UINT8, |
| TDESC_TYPE_UINT16, |
| TDESC_TYPE_UINT32, |
| TDESC_TYPE_UINT64, |
| TDESC_TYPE_UINT128, |
| TDESC_TYPE_CODE_PTR, |
| TDESC_TYPE_DATA_PTR, |
| TDESC_TYPE_IEEE_HALF, |
| TDESC_TYPE_IEEE_SINGLE, |
| TDESC_TYPE_IEEE_DOUBLE, |
| TDESC_TYPE_ARM_FPA_EXT, |
| TDESC_TYPE_I387_EXT, |
| TDESC_TYPE_BFLOAT16, |
| |
| /* Types defined by a target feature. */ |
| TDESC_TYPE_VECTOR, |
| TDESC_TYPE_STRUCT, |
| TDESC_TYPE_UNION, |
| TDESC_TYPE_FLAGS, |
| TDESC_TYPE_ENUM |
| }; |
| |
| struct tdesc_type : tdesc_element |
| { |
| tdesc_type (const std::string &name_, enum tdesc_type_kind kind_) |
| : name (name_), kind (kind_) |
| {} |
| |
| virtual ~tdesc_type () = default; |
| |
| DISABLE_COPY_AND_ASSIGN (tdesc_type); |
| |
| /* The name of this type. */ |
| std::string name; |
| |
| /* Identify the kind of this type. */ |
| enum tdesc_type_kind kind; |
| |
| bool operator== (const tdesc_type &other) const |
| { |
| return name == other.name && kind == other.kind; |
| } |
| |
| bool operator!= (const tdesc_type &other) const |
| { |
| return !(*this == other); |
| } |
| }; |
| |
| typedef std::unique_ptr<tdesc_type> tdesc_type_up; |
| |
| struct tdesc_type_builtin : tdesc_type |
| { |
| tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind) |
| : tdesc_type (name, kind) |
| {} |
| |
| void accept (tdesc_element_visitor &v) const override |
| { |
| v.visit (this); |
| } |
| }; |
| |
| /* tdesc_type for vector types. */ |
| |
| struct tdesc_type_vector : tdesc_type |
| { |
| tdesc_type_vector (const std::string &name, tdesc_type *element_type_, |
| int count_) |
| : tdesc_type (name, TDESC_TYPE_VECTOR), |
| element_type (element_type_), count (count_) |
| {} |
| |
| void accept (tdesc_element_visitor &v) const override |
| { |
| v.visit (this); |
| } |
| |
| struct tdesc_type *element_type; |
| int count; |
| }; |
| |
| /* A named type from a target description. */ |
| |
| struct tdesc_type_field |
| { |
| tdesc_type_field (const std::string &name_, tdesc_type *type_, |
| int start_, int end_) |
| : name (name_), type (type_), start (start_), end (end_) |
| {} |
| |
| std::string name; |
| struct tdesc_type *type; |
| /* For non-enum-values, either both are -1 (non-bitfield), or both are |
| not -1 (bitfield). For enum values, start is the value (which could be |
| -1), end is -1. */ |
| int start, end; |
| }; |
| |
| /* tdesc_type for struct, union, flags, and enum types. */ |
| |
| struct tdesc_type_with_fields : tdesc_type |
| { |
| tdesc_type_with_fields (const std::string &name, tdesc_type_kind kind, |
| int size_ = 0) |
| : tdesc_type (name, kind), size (size_) |
| {} |
| |
| void accept (tdesc_element_visitor &v) const override |
| { |
| v.visit (this); |
| } |
| |
| std::vector<tdesc_type_field> fields; |
| int size; |
| }; |
| |
| /* A feature from a target description. Each feature is a collection |
| of other elements, e.g. registers and types. */ |
| |
| struct tdesc_feature : tdesc_element |
| { |
| tdesc_feature (const std::string &name_) |
| : name (name_) |
| {} |
| |
| virtual ~tdesc_feature () = default; |
| |
| DISABLE_COPY_AND_ASSIGN (tdesc_feature); |
| |
| /* The name of this feature. It may be recognized by the architecture |
| support code. */ |
| std::string name; |
| |
| /* The registers associated with this feature. */ |
| std::vector<tdesc_reg_up> registers; |
| |
| /* The types associated with this feature. */ |
| std::vector<tdesc_type_up> types; |
| |
| void accept (tdesc_element_visitor &v) const override; |
| |
| bool operator== (const tdesc_feature &other) const; |
| |
| bool operator!= (const tdesc_feature &other) const |
| { |
| return !(*this == other); |
| } |
| }; |
| |
| typedef std::unique_ptr<tdesc_feature> tdesc_feature_up; |
| |
| /* A deleter adapter for a target_desc. There are different |
| implementations of this deleter class in gdb and gdbserver because even |
| though the target_desc name is shared between the two projects, the |
| actual implementations of target_desc are completely different. */ |
| |
| struct target_desc_deleter |
| { |
| void operator() (struct target_desc *desc) const; |
| }; |
| |
| /* A unique pointer specialization that holds a target_desc. */ |
| |
| typedef std::unique_ptr<target_desc, target_desc_deleter> target_desc_up; |
| |
| /* Allocate a new target_desc. */ |
| target_desc_up allocate_target_description (void); |
| |
| /* Set TARGET_DESC's architecture by NAME. */ |
| void set_tdesc_architecture (target_desc *target_desc, |
| const char *name); |
| |
| /* Return the architecture associated with this target description as a string, |
| or NULL if no architecture was specified. */ |
| const char *tdesc_architecture_name (const struct target_desc *target_desc); |
| |
| /* Set TARGET_DESC's osabi by NAME. */ |
| void set_tdesc_osabi (target_desc *target_desc, const char *name); |
| |
| /* Return the osabi associated with this target description as a string, |
| or NULL if no osabi was specified. */ |
| const char *tdesc_osabi_name (const struct target_desc *target_desc); |
| |
| /* Return the type associated with ID in the context of FEATURE, or |
| NULL if none. */ |
| struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature, |
| const char *id); |
| |
| /* Return the created feature named NAME in target description TDESC. */ |
| struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc, |
| const char *name); |
| |
| /* Return the created vector tdesc_type named NAME in FEATURE. */ |
| struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature, |
| const char *name, |
| struct tdesc_type *field_type, |
| int count); |
| |
| /* Return the created struct tdesc_type named NAME in FEATURE. */ |
| tdesc_type_with_fields *tdesc_create_struct (struct tdesc_feature *feature, |
| const char *name); |
| |
| /* Return the created union tdesc_type named NAME in FEATURE. */ |
| tdesc_type_with_fields *tdesc_create_union (struct tdesc_feature *feature, |
| const char *name); |
| |
| /* Return the created flags tdesc_type named NAME in FEATURE. */ |
| tdesc_type_with_fields *tdesc_create_flags (struct tdesc_feature *feature, |
| const char *name, |
| int size); |
| |
| /* Return the created enum tdesc_type named NAME in FEATURE. */ |
| tdesc_type_with_fields *tdesc_create_enum (struct tdesc_feature *feature, |
| const char *name, |
| int size); |
| |
| /* Add a new field to TYPE. FIELD_NAME is its name, and FIELD_TYPE is |
| its type. */ |
| void tdesc_add_field (tdesc_type_with_fields *type, const char *field_name, |
| struct tdesc_type *field_type); |
| |
| /* Add a new bitfield to TYPE, with range START to END. FIELD_NAME is its name, |
| and FIELD_TYPE is its type. */ |
| void tdesc_add_typed_bitfield (tdesc_type_with_fields *type, |
| const char *field_name, |
| int start, int end, |
| struct tdesc_type *field_type); |
| |
| /* Set the total length of TYPE. Structs which contain bitfields may |
| omit the reserved bits, so the end of the last field may not |
| suffice. */ |
| void tdesc_set_struct_size (tdesc_type_with_fields *type, int size); |
| |
| /* Add a new untyped bitfield to TYPE. |
| Untyped bitfields become either uint32 or uint64 depending on the size |
| of the underlying type. */ |
| void tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name, |
| int start, int end); |
| |
| /* A flag is just a typed(bool) single-bit bitfield. |
| This function is kept to minimize changes in generated files. */ |
| void tdesc_add_flag (tdesc_type_with_fields *type, int start, |
| const char *flag_name); |
| |
| /* Add field with VALUE and NAME to the enum TYPE. */ |
| void tdesc_add_enum_value (tdesc_type_with_fields *type, int value, |
| const char *name); |
| |
| /* Create a register in feature FEATURE. */ |
| void tdesc_create_reg (struct tdesc_feature *feature, const char *name, |
| int regnum, int save_restore, const char *group, |
| int bitsize, const char *type); |
| |
| /* Return the tdesc in string XML format. */ |
| |
| const char *tdesc_get_features_xml (const target_desc *tdesc); |
| |
| /* Print target description as xml. */ |
| |
| class print_xml_feature : public tdesc_element_visitor |
| { |
| public: |
| print_xml_feature (std::string *buffer_) |
| : m_buffer (buffer_), |
| m_depth (0) |
| {} |
| |
| void visit_pre (const target_desc *e) override; |
| void visit_post (const target_desc *e) override; |
| void visit_pre (const tdesc_feature *e) override; |
| void visit_post (const tdesc_feature *e) override; |
| void visit (const tdesc_type_builtin *type) override; |
| void visit (const tdesc_type_vector *type) override; |
| void visit (const tdesc_type_with_fields *type) override; |
| void visit (const tdesc_reg *reg) override; |
| |
| private: |
| |
| /* Called with a positive value of ADJUST when we move inside an element, |
| for example inside <target>, and with a negative value when we leave |
| the element. In this class this function does nothing, but a |
| sub-class can override this to track the current level of nesting. */ |
| void indent (int adjust) |
| { |
| m_depth += (adjust * 2); |
| } |
| |
| /* Functions to add lines to the output buffer M_BUFFER. Each of these |
| functions appends a newline, so don't include one in the strings being |
| passed. */ |
| void add_line (const std::string &str); |
| void add_line (const char *fmt, ...) ATTRIBUTE_PRINTF (2, 3); |
| |
| /* The buffer we are writing too. */ |
| std::string *m_buffer; |
| |
| /* The current indentation depth. */ |
| int m_depth; |
| }; |
| |
| #endif /* COMMON_TDESC_H */ |