From 08da556929d8736cb2c29d0f58caa5a73922cea5 Mon Sep 17 00:00:00 2001 From: Thiago Jung Bauermann Date: Sat, 26 Apr 2025 16:14:02 -0300 Subject: [PATCH] gdbserver: Support target description parameters Nothing uses it yet. --- gdbserver/target.cc | 14 ++++++++ gdbserver/target.h | 20 +++++++++++ gdbserver/tdesc.cc | 87 +++++++++++++++++++++++++++++++++++++++------ gdbserver/tdesc.h | 28 +++++++++++++++ gdbsupport/tdesc.h | 6 ---- 5 files changed, 138 insertions(+), 17 deletions(-) diff --git a/gdbserver/target.cc b/gdbserver/target.cc index 4838b39da43..47203617c02 100644 --- a/gdbserver/target.cc +++ b/gdbserver/target.cc @@ -850,3 +850,17 @@ process_stratum_target::get_ipa_tdesc_idx () { return 0; } + +ULONGEST +process_stratum_target::tdesc_parameter_value (regcache *regcache, + unsigned int param_id) +{ + error (_("Target does not support target description parameters.")); +} + +bool +process_stratum_target::is_register_relevant_for_tdesc_parameter + (const target_desc *tdesc, int regnum) +{ + return false; +} diff --git a/gdbserver/target.h b/gdbserver/target.h index af788e256eb..e84ba2644f1 100644 --- a/gdbserver/target.h +++ b/gdbserver/target.h @@ -523,6 +523,13 @@ public: Returns true if successful and false otherwise. */ virtual bool store_memtags (CORE_ADDR address, size_t len, const gdb::byte_vector &tags, int type); + + + virtual ULONGEST tdesc_parameter_value (regcache *regcache, + unsigned int param_id); + + virtual bool is_register_relevant_for_tdesc_parameter + (const target_desc *tdesc, int regnum); }; extern process_stratum_target *the_target; @@ -748,4 +755,17 @@ target_thread_id_str (thread_info *thread) return the_target->thread_id_str (thread); } +static inline ULONGEST +target_desc_parameter_value (regcache *regcache, unsigned int param_id) +{ + return the_target->tdesc_parameter_value (regcache, param_id); +} + +static inline bool +target_is_register_relevant_for_tdesc_parameter (const target_desc *tdesc, + int regnum) +{ + return the_target->is_register_relevant_for_tdesc_parameter (tdesc, regnum); +} + #endif /* GDBSERVER_TARGET_H */ diff --git a/gdbserver/tdesc.cc b/gdbserver/tdesc.cc index 54c105c54ec..d0c8f99357d 100644 --- a/gdbserver/tdesc.cc +++ b/gdbserver/tdesc.cc @@ -51,6 +51,65 @@ void target_desc::accept (tdesc_element_visitor &v) const #endif } +/* Return bit size of given TYPE. */ + +static unsigned int +tdesc_type_bitsize (const tdesc_type *type) +{ + switch (type->kind) { + case TDESC_TYPE_INT8: + case TDESC_TYPE_UINT8: + return 8; + case TDESC_TYPE_IEEE_HALF: + case TDESC_TYPE_INT16: + case TDESC_TYPE_UINT16: + case TDESC_TYPE_BFLOAT16: + return 16; + case TDESC_TYPE_IEEE_SINGLE: + case TDESC_TYPE_INT32: + case TDESC_TYPE_UINT32: + return 32; + case TDESC_TYPE_IEEE_DOUBLE: + case TDESC_TYPE_INT64: + case TDESC_TYPE_UINT64: + return 64; + case TDESC_TYPE_I387_EXT: + return 80; + case TDESC_TYPE_ARM_FPA_EXT: + return 96; + case TDESC_TYPE_INT128: + case TDESC_TYPE_UINT128: + return 128; + default: + /* The other types require a gdbarch to determine their size. */ + error ("Target description uses unsupported type in variable-size register."); + } +} + +/* FIXME: Document. */ + +std::optional +tdesc_parameter_id (const target_desc *tdesc, const char *feature, + const char *param_name) +{ + for (int i = 0; i < tdesc->parameters.size (); i++) + { + const tdesc_arch_parameter ¶meter = tdesc->parameters[i]; + if (parameter.feature == feature && parameter.name == param_name) + return i; + } + + return {}; +} + +/* FIXME: Document. */ + +unsigned int +tdesc_parameter_size (const target_desc *tdesc, unsigned param_id) +{ + return tdesc->parameters[param_id].size; +} + void init_target_desc (struct target_desc *tdesc, const char **expedite_regs, @@ -60,20 +119,26 @@ init_target_desc (struct target_desc *tdesc, /* Go through all the features and populate reg_defs. */ for (const tdesc_feature_up &feature : tdesc->features) - for (const tdesc_reg_up &treg : feature->registers) - { - int regnum = treg->target_regnum; + { + for (const tdesc_parameter_up ¶meter: feature->parameters) + tdesc->parameters.emplace_back (parameter->feature, parameter->name, + tdesc_type_bitsize (parameter->type) / 8); - /* Register number will increase (possibly with gaps) or be zero. */ - gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ()); + for (const tdesc_reg_up &treg : feature->registers) + { + int regnum = treg->target_regnum; - if (regnum != 0) - tdesc->reg_defs.resize (regnum, gdb::reg (offset)); + /* Register number will increase (possibly with gaps) or be zero. */ + gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ()); - tdesc->reg_defs.emplace_back (treg->name.c_str (), offset, - treg->bitsize); - offset += treg->bitsize; - } + if (regnum != 0) + tdesc->reg_defs.resize (regnum, gdb::reg (offset)); + + tdesc->reg_defs.emplace_back (treg->name.c_str (), offset, + treg->bitsize); + offset += treg->bitsize; + } + } tdesc->registers_size = offset / 8; diff --git a/gdbserver/tdesc.h b/gdbserver/tdesc.h index 58b2395aaa0..45b9b48c97e 100644 --- a/gdbserver/tdesc.h +++ b/gdbserver/tdesc.h @@ -25,6 +25,23 @@ #include "regdef.h" #include +struct tdesc_arch_parameter +{ + tdesc_arch_parameter (std::string &feature_, std::string &name_, + unsigned int size_) + : feature (feature_), name (name_), size (size_) + {} + + /* Feature to which the parameter belongs. */ + std::string feature; + + /* The name of the parameter. */ + std::string name; + + /* The size of a parameter value. */ + unsigned int size; +}; + /* A target description. Inherit from tdesc_feature so that target_desc can be used as tdesc_feature. */ @@ -40,6 +57,9 @@ struct target_desc final : tdesc_element /* XML features in this target description. */ std::vector features; + /* The index into the vector is the internal ID for the parameter. */ + std::vector parameters; + #ifndef IN_PROCESS_AGENT /* A vector of register names. These are the "expedite" registers: registers whose values are sent along with stop replies. */ @@ -98,4 +118,12 @@ const struct target_desc *current_target_desc (void); bool tdesc_contains_feature (const target_desc *tdesc, const std::string &feature); +/* FIXME: Document. */ +unsigned int tdesc_parameter_size (const target_desc *tdesc, unsigned param_id); + +/* FIXME: Document. */ +std::optional tdesc_parameter_id (const target_desc *tdesc, + const char *feature, + const char *param_name); + #endif /* GDBSERVER_TDESC_H */ diff --git a/gdbsupport/tdesc.h b/gdbsupport/tdesc.h index b7b8bca5c10..46549bd5bf4 100644 --- a/gdbsupport/tdesc.h +++ b/gdbsupport/tdesc.h @@ -536,12 +536,6 @@ void tdesc_create_reg (struct tdesc_feature *feature, const char *name, const tdesc_parameter &bitsize_parameter, const char *type); -/* Return internal ID of PARAMETER from FEATURE. */ - -std::optional tdesc_parameter_id (const target_desc *target_desc, - const char *feature, - const char *parameter); - /* Add PARAMETER to FEATURE. */ const tdesc_parameter & tdesc_create_parameter (tdesc_feature &feature, -- 2.47.2