Add MI "-break-insert --qualified"
[deliverable/binutils-gdb.git] / gdb / target-descriptions.c
index 3186bf886fc5f1b62e0ff77a4e5a2bc0fe52b250..6778b93400b80eb63a1168a2ce47ef0ce411cb6f 100644 (file)
@@ -1,6 +1,6 @@
 /* Target description support for GDB.
 
-   Copyright (C) 2006-2018 Free Software Foundation, Inc.
+   Copyright (C) 2006-2020 Free Software Foundation, Inc.
 
    Contributed by CodeSourcery.
 
@@ -26,7 +26,6 @@
 #include "reggroups.h"
 #include "target.h"
 #include "target-descriptions.h"
-#include "vec.h"
 #include "xml-support.h"
 #include "xml-tdesc.h"
 #include "osabi.h"
@@ -50,129 +49,6 @@ struct property
   std::string value;
 };
 
-/* 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;
-};
-
-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_SINGLE,
-  TDESC_TYPE_IEEE_DOUBLE,
-  TDESC_TYPE_ARM_FPA_EXT,
-  TDESC_TYPE_I387_EXT,
-
-  /* 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;
-};
-
-/* 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;
-};
-
 /* Convert a tdesc_type to a gdb type.  */
 
 static type *
@@ -242,6 +118,11 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
 
       switch (e->kind)
        {
+       case TDESC_TYPE_IEEE_HALF:
+         m_type = arch_float_type (m_gdbarch, -1, "builtin_type_ieee_half",
+                                   floatformats_ieee_half);
+         return;
+
        case TDESC_TYPE_IEEE_SINGLE:
          m_type = arch_float_type (m_gdbarch, -1, "builtin_type_ieee_single",
                                    floatformats_ieee_single);
@@ -260,6 +141,11 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
          m_type = arch_float_type (m_gdbarch, -1, "builtin_type_i387_ext",
                                    floatformats_i387_ext);
          return;
+
+       case TDESC_TYPE_BFLOAT16:
+         m_type = arch_float_type (m_gdbarch, -1, "builtin_type_bfloat16",
+                                   floatformats_bfloat16);
+         return;
        }
 
       internal_error (__FILE__, __LINE__,
@@ -275,7 +161,7 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
 
       type *element_gdb_type = make_gdb_type (m_gdbarch, e->element_type);
       m_type = init_vector_type (element_gdb_type, e->count);
-      TYPE_NAME (m_type) = xstrdup (e->name.c_str ());
+      m_type->set_name (xstrdup (e->name.c_str ()));
       return;
     }
 
@@ -311,8 +197,7 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
     void make_gdb_type_struct (const tdesc_type_with_fields *e)
     {
       m_type = arch_composite_type (m_gdbarch, NULL, TYPE_CODE_STRUCT);
-      TYPE_NAME (m_type) = xstrdup (e->name.c_str ());
-      TYPE_TAG_NAME (m_type) = TYPE_NAME (m_type);
+      m_type->set_name (xstrdup (e->name.c_str ()));
 
       for (const tdesc_type_field &f : e->fields)
        {
@@ -344,7 +229,7 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
                 the total size of the structure.  */
              bitsize = f.end - f.start + 1;
              total_size = e->size * TARGET_CHAR_BIT;
-             if (gdbarch_bits_big_endian (m_gdbarch))
+             if (gdbarch_byte_order (m_gdbarch) == BFD_ENDIAN_BIG)
                SET_FIELD_BITPOS (fld[0], total_size - f.start - bitsize);
              else
                SET_FIELD_BITPOS (fld[0], f.start);
@@ -367,7 +252,7 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
     void make_gdb_type_union (const tdesc_type_with_fields *e)
     {
       m_type = arch_composite_type (m_gdbarch, NULL, TYPE_CODE_UNION);
-      TYPE_NAME (m_type) = xstrdup (e->name.c_str ());
+      m_type->set_name (xstrdup (e->name.c_str ()));
 
       for (const tdesc_type_field &f : e->fields)
        {
@@ -428,82 +313,29 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
   return gdb_type.get_type ();
 }
 
-/* A feature from a target description.  Each feature is a collection
-   of other elements, e.g. registers and types.  */
+/* Wrapper around bfd_arch_info_type.  A class with this name is used in
+   the API that is shared between gdb and gdbserver code, but gdbserver
+   doesn't use compatibility information, so its version of this class is
+   empty.  */
 
-struct tdesc_feature : tdesc_element
+class tdesc_compatible_info
 {
-  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
-  {
-    v.visit_pre (this);
-
-    for (const tdesc_type_up &type : types)
-      type->accept (v);
-
-    for (const tdesc_reg_up &reg : registers)
-      reg->accept (v);
-
-    v.visit_post (this);
-  }
-
-  bool operator== (const tdesc_feature &other) const
-  {
-    if (name != other.name)
-      return false;
-
-    if (registers.size () != other.registers.size ())
-      return false;
-
-    for (int ix = 0; ix < registers.size (); ix++)
-      {
-       const tdesc_reg_up &reg1 = registers[ix];
-       const tdesc_reg_up &reg2 = other.registers[ix];
-
-       if (reg1 != reg2 && *reg1 != *reg2)
-         return false;
-      }
-
-    if (types.size () != other.types.size ())
-      return false;
-
-    for (int ix = 0; ix < types.size (); ix++)
-      {
-       const tdesc_type_up &type1 = types[ix];
-       const tdesc_type_up &type2 = other.types[ix];
-
-       if (type1 != type2 && *type1 != *type2)
-         return false;
-      }
+public:
+  /* Constructor.  */
+  explicit tdesc_compatible_info (const bfd_arch_info_type *arch)
+    : m_arch (arch)
+  { /* Nothing.  */ }
 
-    return true;
-  }
+  /* Access the contained pointer.  */
+  const bfd_arch_info_type *arch () const
+  { return m_arch; }
 
-  bool operator!= (const tdesc_feature &other) const
-  {
-    return !(*this == other);
-  }
+private:
+  /* Architecture information looked up from the <compatible> entity within
+     a target description.  */
+  const bfd_arch_info_type *m_arch;
 };
 
-typedef std::unique_ptr<tdesc_feature> tdesc_feature_up;
-
 /* A target description.  */
 
 struct target_desc : tdesc_element
@@ -524,7 +356,7 @@ struct target_desc : tdesc_element
   enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
   /* The list of compatible architectures reported by the target.  */
-  std::vector<const bfd_arch_info *> compatible;
+  std::vector<tdesc_compatible_info_up> compatible;
 
   /* Any architecture-specific properties specified by the target.  */
   std::vector<property> properties;
@@ -532,6 +364,9 @@ struct target_desc : tdesc_element
   /* The features associated with this target.  */
   std::vector<tdesc_feature_up> features;
 
+  /* Used to cache the generated xml version of the target description.  */
+  mutable char *xmltarget = nullptr;
+
   void accept (tdesc_element_visitor &v) const override
   {
     v.visit_pre (this);
@@ -717,11 +552,11 @@ target_find_description (void)
   /* Next try to read the description from the current target using
      target objects.  */
   if (current_target_desc == NULL)
-    current_target_desc = target_read_description_xml (&current_target);
+    current_target_desc = target_read_description_xml (current_top_target ());
 
   /* If that failed try a target-specific hook.  */
   if (current_target_desc == NULL)
-    current_target_desc = target_read_description (&current_target);
+    current_target_desc = target_read_description (current_top_target ());
 
   /* If a non-NULL description was returned, then update the current
      architecture.  */
@@ -791,11 +626,11 @@ int
 tdesc_compatible_p (const struct target_desc *target_desc,
                    const struct bfd_arch_info *arch)
 {
-  for (const bfd_arch_info *compat : target_desc->compatible)
+  for (const tdesc_compatible_info_up &compat : target_desc->compatible)
     {
-      if (compat == arch
-         || arch->compatible (arch, compat)
-         || compat->compatible (compat, arch))
+      if (compat->arch () == arch
+         || arch->compatible (arch, compat->arch ())
+         || compat->arch ()->compatible (compat->arch (), arch))
        return 1;
     }
 
@@ -827,6 +662,32 @@ tdesc_architecture (const struct target_desc *target_desc)
   return target_desc->arch;
 }
 
+/* See gdbsupport/tdesc.h.  */
+
+const char *
+tdesc_architecture_name (const struct target_desc *target_desc)
+{
+  if (target_desc->arch != NULL)
+    return target_desc->arch->printable_name;
+  return NULL;
+}
+
+/* See gdbsupport/tdesc.h.  */
+
+const std::vector<tdesc_compatible_info_up> &
+tdesc_compatible_info_list (const target_desc *target_desc)
+{
+  return target_desc->compatible;
+}
+
+/* See gdbsupport/tdesc.h.  */
+
+const char *
+tdesc_compatible_info_arch_name (const tdesc_compatible_info_up &compatible)
+{
+  return compatible->arch ()->printable_name;
+}
+
 /* Return the OSABI associated with this target description, or
    GDB_OSABI_UNKNOWN if no osabi was specified.  */
 
@@ -836,7 +697,16 @@ tdesc_osabi (const struct target_desc *target_desc)
   return target_desc->osabi;
 }
 
-\f
+/* See gdbsupport/tdesc.h.  */
+
+const char *
+tdesc_osabi_name (const struct target_desc *target_desc)
+{
+  enum gdb_osabi osabi = tdesc_osabi (target_desc);
+  if (osabi > GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
+    return gdbarch_osabi_name (osabi);
+  return nullptr;
+}
 
 /* Return 1 if this target description includes any registers.  */
 
@@ -875,58 +745,6 @@ tdesc_feature_name (const struct tdesc_feature *feature)
   return feature->name.c_str ();
 }
 
-/* Predefined types.  */
-static tdesc_type_builtin tdesc_predefined_types[] =
-{
-  { "bool", TDESC_TYPE_BOOL },
-  { "int8", TDESC_TYPE_INT8 },
-  { "int16", TDESC_TYPE_INT16 },
-  { "int32", TDESC_TYPE_INT32 },
-  { "int64", TDESC_TYPE_INT64 },
-  { "int128", TDESC_TYPE_INT128 },
-  { "uint8", TDESC_TYPE_UINT8 },
-  { "uint16", TDESC_TYPE_UINT16 },
-  { "uint32", TDESC_TYPE_UINT32 },
-  { "uint64", TDESC_TYPE_UINT64 },
-  { "uint128", TDESC_TYPE_UINT128 },
-  { "code_ptr", TDESC_TYPE_CODE_PTR },
-  { "data_ptr", TDESC_TYPE_DATA_PTR },
-  { "ieee_single", TDESC_TYPE_IEEE_SINGLE },
-  { "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
-  { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
-  { "i387_ext", TDESC_TYPE_I387_EXT }
-};
-
-/* Lookup a predefined type.  */
-
-static struct tdesc_type *
-tdesc_predefined_type (enum tdesc_type_kind kind)
-{
-  for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
-    if (tdesc_predefined_types[ix].kind == kind)
-      return &tdesc_predefined_types[ix];
-
-  gdb_assert_not_reached ("bad predefined tdesc type");
-}
-
-/* See common/tdesc.h.  */
-
-struct tdesc_type *
-tdesc_named_type (const struct tdesc_feature *feature, const char *id)
-{
-  /* First try target-defined types.  */
-  for (const tdesc_type_up &type : feature->types)
-    if (type->name == id)
-      return type.get ();
-
-  /* Next try the predefined types.  */
-  for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
-    if (tdesc_predefined_types[ix].name == id)
-      return &tdesc_predefined_types[ix];
-
-  return NULL;
-}
-
 /* Lookup type associated with ID.  */
 
 struct type *
@@ -954,12 +772,7 @@ tdesc_find_type (struct gdbarch *gdbarch, const char *id)
 static void *
 tdesc_data_init (struct obstack *obstack)
 {
-  struct tdesc_arch_data *data;
-
-  data = OBSTACK_ZALLOC (obstack, struct tdesc_arch_data);
-  new (data) tdesc_arch_data ();
-
-  return data;
+  return obstack_new<tdesc_arch_data> (obstack);
 }
 
 /* Similar, but for the temporary copy used during architecture
@@ -1053,8 +866,7 @@ tdesc_numbered_register_choices (const struct tdesc_feature *feature,
    bits.  The register must exist.  */
 
 int
-tdesc_register_size (const struct tdesc_feature *feature,
-                    const char *name)
+tdesc_register_bitsize (const struct tdesc_feature *feature, const char *name)
 {
   struct tdesc_reg *reg = tdesc_find_register_early (feature, name);
 
@@ -1092,12 +904,11 @@ tdesc_register_name (struct gdbarch *gdbarch, int regno)
 {
   struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
   int num_regs = gdbarch_num_regs (gdbarch);
-  int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);
 
   if (reg != NULL)
     return reg->name.c_str ();
 
-  if (regno >= num_regs && regno < num_regs + num_pseudo_regs)
+  if (regno >= num_regs && regno < gdbarch_num_cooked_regs (gdbarch))
     {
       struct tdesc_arch_data *data
        = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
@@ -1291,7 +1102,8 @@ set_tdesc_pseudo_register_reggroup_p
 void
 tdesc_use_registers (struct gdbarch *gdbarch,
                     const struct target_desc *target_desc,
-                    struct tdesc_arch_data *early_data)
+                    struct tdesc_arch_data *early_data,
+                    tdesc_unknown_register_ftype unk_reg_cb)
 {
   int num_regs = gdbarch_num_regs (gdbarch);
   struct tdesc_arch_data *data;
@@ -1340,6 +1152,34 @@ tdesc_use_registers (struct gdbarch *gdbarch,
   while (data->arch_regs.size () < num_regs)
     data->arch_regs.emplace_back (nullptr, nullptr);
 
+  /* First we give the target a chance to number previously unknown
+     registers.  This allows targets to record the numbers assigned based
+     on which feature the register was from.  */
+  if (unk_reg_cb != NULL)
+    {
+      for (const tdesc_feature_up &feature : target_desc->features)
+       for (const tdesc_reg_up &reg : feature->registers)
+         if (htab_find (reg_hash, reg.get ()) != NULL)
+           {
+             int regno = unk_reg_cb (gdbarch, feature.get (),
+                                     reg->name.c_str (), num_regs);
+             gdb_assert (regno == -1 || regno >= num_regs);
+             if (regno != -1)
+               {
+                 while (regno >= data->arch_regs.size ())
+                   data->arch_regs.emplace_back (nullptr, nullptr);
+                 data->arch_regs[regno] = tdesc_arch_reg (reg.get (), NULL);
+                 num_regs = regno + 1;
+                 htab_remove_elt (reg_hash, reg.get ());
+               }
+           }
+    }
+
+  /* Ensure the array was sized correctly above.  */
+  gdb_assert (data->arch_regs.size () == num_regs);
+
+  /* Now in a final pass we assign register numbers to any remaining
+     unnumbered registers.  */
   for (const tdesc_feature_up &feature : target_desc->features)
     for (const tdesc_reg_up &reg : feature->registers)
       if (htab_find (reg_hash, reg.get ()) != NULL)
@@ -1358,167 +1198,11 @@ tdesc_use_registers (struct gdbarch *gdbarch,
                                      tdesc_remote_register_number);
   set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p);
 }
-\f
-
-/* See common/tdesc.h.  */
 
-void
-tdesc_create_reg (struct tdesc_feature *feature, const char *name,
-                 int regnum, int save_restore, const char *group,
-                 int bitsize, const char *type)
-{
-  tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore,
-                                 group, bitsize, type);
-
-  feature->registers.emplace_back (reg);
-}
-
-/* See common/tdesc.h.  */
-
-struct tdesc_type *
-tdesc_create_vector (struct tdesc_feature *feature, const char *name,
-                    struct tdesc_type *field_type, int count)
-{
-  tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count);
-  feature->types.emplace_back (type);
-
-  return type;
-}
-
-/* See common/tdesc.h.  */
-
-tdesc_type_with_fields *
-tdesc_create_struct (struct tdesc_feature *feature, const char *name)
-{
-  tdesc_type_with_fields *type
-    = new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT);
-  feature->types.emplace_back (type);
-
-  return type;
-}
-
-/* See common/tdesc.h.  */
-
-void
-tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
-{
-  gdb_assert (type->kind == TDESC_TYPE_STRUCT);
-  gdb_assert (size > 0);
-  type->size = size;
-}
-
-/* See common/tdesc.h.  */
-
-tdesc_type_with_fields *
-tdesc_create_union (struct tdesc_feature *feature, const char *name)
-{
-  tdesc_type_with_fields *type
-    = new tdesc_type_with_fields (name, TDESC_TYPE_UNION);
-  feature->types.emplace_back (type);
-
-  return type;
-}
-
-/* See common/tdesc.h.  */
-
-tdesc_type_with_fields *
-tdesc_create_flags (struct tdesc_feature *feature, const char *name,
-                   int size)
-{
-  gdb_assert (size > 0);
-
-  tdesc_type_with_fields *type
-    = new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size);
-  feature->types.emplace_back (type);
-
-  return type;
-}
-
-tdesc_type_with_fields *
-tdesc_create_enum (struct tdesc_feature *feature, const char *name,
-                  int size)
-{
-  gdb_assert (size > 0);
-
-  tdesc_type_with_fields *type
-    = new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size);
-  feature->types.emplace_back (type);
-
-  return type;
-}
-
-/* See common/tdesc.h.  */
-
-void
-tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
-                struct tdesc_type *field_type)
-{
-  gdb_assert (type->kind == TDESC_TYPE_UNION
-             || type->kind == TDESC_TYPE_STRUCT);
-
-  /* Initialize start and end so we know this is not a bit-field
-     when we print-c-tdesc.  */
-  type->fields.emplace_back (field_name, field_type, -1, -1);
-}
-
-void
-tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name,
-                         int start, int end, struct tdesc_type *field_type)
-{
-  gdb_assert (type->kind == TDESC_TYPE_STRUCT
-             || type->kind == TDESC_TYPE_FLAGS);
-  gdb_assert (start >= 0 && end >= start);
-
-  type->fields.emplace_back (field_name, field_type, start, end);
-}
-
-/* See common/tdesc.h.  */
-
-void
-tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
-                   int start, int end)
-{
-  struct tdesc_type *field_type;
-
-  gdb_assert (start >= 0 && end >= start);
-
-  if (type->size > 4)
-    field_type = tdesc_predefined_type (TDESC_TYPE_UINT64);
-  else
-    field_type = tdesc_predefined_type (TDESC_TYPE_UINT32);
-
-  tdesc_add_typed_bitfield (type, field_name, start, end, field_type);
-}
-
-/* See common/tdesc.h.  */
-
-void
-tdesc_add_flag (tdesc_type_with_fields *type, int start,
-               const char *flag_name)
-{
-  gdb_assert (type->kind == TDESC_TYPE_FLAGS
-             || type->kind == TDESC_TYPE_STRUCT);
-
-  type->fields.emplace_back (flag_name,
-                            tdesc_predefined_type (TDESC_TYPE_BOOL),
-                            start, start);
-}
-
-void
-tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
-                     const char *name)
-{
-  gdb_assert (type->kind == TDESC_TYPE_ENUM);
-  type->fields.emplace_back (name,
-                            tdesc_predefined_type (TDESC_TYPE_INT32),
-                            value, -1);
-}
-
-/* See common/tdesc.h.  */
+/* See gdbsupport/tdesc.h.  */
 
 struct tdesc_feature *
-tdesc_create_feature (struct target_desc *tdesc, const char *name,
-                     const char *xml)
+tdesc_create_feature (struct target_desc *tdesc, const char *name)
 {
   struct tdesc_feature *new_feature = new tdesc_feature (name);
 
@@ -1527,24 +1211,20 @@ tdesc_create_feature (struct target_desc *tdesc, const char *name,
   return new_feature;
 }
 
+/* See gdbsupport/tdesc.h.  */
+
 struct target_desc *
 allocate_target_description (void)
 {
   return new target_desc ();
 }
 
-static void
-free_target_description (void *arg)
-{
-  struct target_desc *target_desc = (struct target_desc *) arg;
+/* See gdbsupport/tdesc.h.  */
 
-  delete target_desc;
-}
-
-struct cleanup *
-make_cleanup_free_target_description (struct target_desc *target_desc)
+void
+target_desc_deleter::operator() (struct target_desc *target_desc) const
 {
-  return make_cleanup (free_target_description, target_desc);
+  delete target_desc;
 }
 
 void
@@ -1557,14 +1237,16 @@ tdesc_add_compatible (struct target_desc *target_desc,
   if (compatible == NULL)
     return;
 
-  for (const bfd_arch_info *compat : target_desc->compatible)
-    if (compat == compatible)
+  for (const tdesc_compatible_info_up &compat : target_desc->compatible)
+    if (compat->arch () == compatible)
       internal_error (__FILE__, __LINE__,
                      _("Attempted to add duplicate "
                        "compatible architecture \"%s\""),
                      compatible->printable_name);
 
-  target_desc->compatible.push_back (compatible);
+  target_desc->compatible.push_back
+    (std::unique_ptr<tdesc_compatible_info>
+     (new tdesc_compatible_info (compatible)));
 }
 
 void
@@ -1580,7 +1262,7 @@ set_tdesc_property (struct target_desc *target_desc,
   target_desc->properties.emplace_back (key, value);
 }
 
-/* See common/tdesc.h.  */
+/* See gdbsupport/tdesc.h.  */
 
 void
 set_tdesc_architecture (struct target_desc *target_desc,
@@ -1596,7 +1278,7 @@ set_tdesc_architecture (struct target_desc *target_desc,
   target_desc->arch = arch;
 }
 
-/* See common/tdesc.h.  */
+/* See gdbsupport/tdesc.h.  */
 
 void
 set_tdesc_osabi (struct target_desc *target_desc, const char *name)
@@ -1616,24 +1298,6 @@ static struct cmd_list_element *tdesc_unset_cmdlist;
 
 /* Helper functions for the CLI commands.  */
 
-static void
-set_tdesc_cmd (const char *args, int from_tty)
-{
-  help_list (tdesc_set_cmdlist, "set tdesc ", all_commands, gdb_stdout);
-}
-
-static void
-show_tdesc_cmd (const char *args, int from_tty)
-{
-  cmd_show_list (tdesc_show_cmdlist, from_tty, "");
-}
-
-static void
-unset_tdesc_cmd (const char *args, int from_tty)
-{
-  help_list (tdesc_unset_cmdlist, "unset tdesc ", all_commands, gdb_stdout);
-}
-
 static void
 set_tdesc_filename_cmd (const char *args, int from_tty,
                        struct cmd_list_element *c)
@@ -1687,6 +1351,8 @@ public:
        break;
       else if (*inp == '-')
        *outp++ = '_';
+      else if (*inp == ' ')
+       *outp++ = '_';
       else
        *outp++ = *inp;
     *outp = '\0';
@@ -1735,10 +1401,10 @@ public:
        printf_unfiltered ("\n");
       }
 
-    for (const bfd_arch_info_type *compatible : e->compatible)
+    for (const tdesc_compatible_info_up &compatible : e->compatible)
       printf_unfiltered
        ("  tdesc_add_compatible (result, bfd_scan_arch (\"%s\"));\n",
-        compatible->printable_name);
+        compatible->arch ()->printable_name);
 
     if (!e->compatible.empty ())
       printf_unfiltered ("\n");
@@ -1961,7 +1627,7 @@ public:
     printf_unfiltered ("  Original: %s */\n\n",
                       lbasename (m_filename_after_features.c_str ()));
 
-    printf_unfiltered ("#include \"common/tdesc.h\"\n");
+    printf_unfiltered ("#include \"gdbsupport/tdesc.h\"\n");
     printf_unfiltered ("\n");
   }
 
@@ -1986,8 +1652,8 @@ public:
     printf_unfiltered ("  struct tdesc_feature *feature;\n");
 
     printf_unfiltered
-      ("\n  feature = tdesc_create_feature (result, \"%s\", \"%s\");\n",
-       e->name.c_str (), lbasename (m_filename_after_features.c_str ()));
+      ("\n  feature = tdesc_create_feature (result, \"%s\");\n",
+       e->name.c_str ());
   }
 
   void visit_post (const tdesc_feature *e) override
@@ -2056,6 +1722,21 @@ private:
   int m_next_regnum = 0;
 };
 
+/* See gdbsupport/tdesc.h.  */
+
+const char *
+tdesc_get_features_xml (const target_desc *tdesc)
+{
+  if (tdesc->xmltarget == nullptr)
+    {
+      std::string buffer ("@");
+      print_xml_feature v (&buffer);
+      tdesc->accept (v);
+      tdesc->xmltarget = xstrdup (buffer.c_str ());
+    }
+  return tdesc->xmltarget;
+}
+
 static void
 maint_print_c_tdesc_cmd (const char *args, int from_tty)
 {
@@ -2082,7 +1763,7 @@ maint_print_c_tdesc_cmd (const char *args, int from_tty)
     error (_("There is no target description to print."));
 
   if (filename == NULL)
-    error (_("The current target description did not come from an XML file."));
+    filename = "fetched from target";
 
   std::string filename_after_features (filename);
   auto loc = filename_after_features.rfind ("/features/");
@@ -2096,8 +1777,11 @@ maint_print_c_tdesc_cmd (const char *args, int from_tty)
   if (startswith (filename_after_features.c_str (), "i386/32bit-")
       || startswith (filename_after_features.c_str (), "i386/64bit-")
       || startswith (filename_after_features.c_str (), "i386/x32-core.xml")
+      || startswith (filename_after_features.c_str (), "riscv/")
       || startswith (filename_after_features.c_str (), "tic6x-")
-      || startswith (filename_after_features.c_str (), "aarch64"))
+      || startswith (filename_after_features.c_str (), "aarch64")
+      || startswith (filename_after_features.c_str (), "arm/")
+      || startswith (filename_after_features.c_str (), "arc/"))
     {
       print_c_feature v (filename_after_features);
 
@@ -2111,23 +1795,98 @@ maint_print_c_tdesc_cmd (const char *args, int from_tty)
     }
 }
 
+/* Implement the maintenance print xml-tdesc command.  */
+
+static void
+maint_print_xml_tdesc_cmd (const char *args, int from_tty)
+{
+  const struct target_desc *tdesc;
+
+  if (args == NULL)
+    {
+      /* Use the global target-supplied description, not the current
+        architecture's.  This lets a GDB for one architecture generate XML
+        for another architecture's description, even though the gdbarch
+        initialization code will reject the new description.  */
+      tdesc = current_target_desc;
+    }
+  else
+    {
+      /* Use the target description from the XML file.  */
+      tdesc = file_read_description_xml (args);
+    }
+
+  if (tdesc == NULL)
+    error (_("There is no target description to print."));
+
+  std::string buf;
+  print_xml_feature v (&buf);
+  tdesc->accept (v);
+  puts_unfiltered (buf.c_str ());
+}
+
 namespace selftests {
 
-static std::vector<std::pair<const char*, const target_desc *>> xml_tdesc;
+/* A reference target description, used for testing (see record_xml_tdesc).  */
+
+struct xml_test_tdesc
+{
+  xml_test_tdesc (const char *name, std::unique_ptr<const target_desc> &&tdesc)
+    : name (name), tdesc (std::move (tdesc))
+  {}
+
+  const char *name;
+  std::unique_ptr<const target_desc> tdesc;
+};
+
+static std::vector<xml_test_tdesc> xml_tdesc;
 
 #if GDB_SELF_TEST
 
-/* See target-descritpions.h.  */
+/* See target-descriptions.h.  */
 
 void
 record_xml_tdesc (const char *xml_file, const struct target_desc *tdesc)
 {
-  xml_tdesc.emplace_back (xml_file, tdesc);
+  xml_tdesc.emplace_back (xml_file, std::unique_ptr<const target_desc> (tdesc));
 }
 #endif
 
 }
 
+/* Test the conversion process of a target description to/from xml: Take a target
+   description TDESC, convert to xml, back to a description, and confirm the new
+   tdesc is identical to the original.  */
+static bool
+maintenance_check_tdesc_xml_convert (const target_desc *tdesc, const char *name)
+{
+  const char *xml = tdesc_get_features_xml (tdesc);
+
+  if (xml == nullptr || *xml != '@')
+    {
+      printf_filtered (_("Could not convert description for %s to xml.\n"),
+                      name);
+      return false;
+    }
+
+  const target_desc *tdesc_trans = string_read_description_xml (xml + 1);
+
+  if (tdesc_trans == nullptr)
+    {
+      printf_filtered (_("Could not convert description for %s from xml.\n"),
+                      name);
+      return false;
+    }
+  else if (*tdesc != *tdesc_trans)
+    {
+      printf_filtered (_("Converted description for %s does not match.\n"),
+                      name);
+      return false;
+    }
+  return true;
+}
+
+
 /* Check that the target descriptions created dynamically by
    architecture-specific code equal the descriptions created from XML files
    found in the specified directory DIR.  */
@@ -2144,40 +1903,49 @@ maintenance_check_xml_descriptions (const char *dir, int from_tty)
 
   for (auto const &e : selftests::xml_tdesc)
     {
-      std::string tdesc_xml = (feature_dir + SLASH_STRING + e.first);
+      std::string tdesc_xml = (feature_dir + SLASH_STRING + e.name);
       const target_desc *tdesc
        = file_read_description_xml (tdesc_xml.data ());
 
-      if (tdesc == NULL || *tdesc != *e.second)
+      if (tdesc == NULL || *tdesc != *e.tdesc)
+       {
+         printf_filtered ( _("Descriptions for %s do not match.\n"), e.name);
+         failed++;
+       }
+      else if (!maintenance_check_tdesc_xml_convert (tdesc, e.name)
+              || !maintenance_check_tdesc_xml_convert (e.tdesc.get (), e.name))
        failed++;
     }
   printf_filtered (_("Tested %lu XML files, %d failed\n"),
                   (long) selftests::xml_tdesc.size (), failed);
 }
 
+void _initialize_target_descriptions ();
 void
-_initialize_target_descriptions (void)
+_initialize_target_descriptions ()
 {
+  cmd_list_element *cmd;
+
   tdesc_data = gdbarch_data_register_pre_init (tdesc_data_init);
 
-  add_prefix_cmd ("tdesc", class_maintenance, set_tdesc_cmd, _("\
+  add_basic_prefix_cmd ("tdesc", class_maintenance, _("\
 Set target description specific variables."),
-                 &tdesc_set_cmdlist, "set tdesc ",
-                 0 /* allow-unknown */, &setlist);
-  add_prefix_cmd ("tdesc", class_maintenance, show_tdesc_cmd, _("\
+                       &tdesc_set_cmdlist, "set tdesc ",
+                       0 /* allow-unknown */, &setlist);
+  add_show_prefix_cmd ("tdesc", class_maintenance, _("\
 Show target description specific variables."),
-                 &tdesc_show_cmdlist, "show tdesc ",
-                 0 /* allow-unknown */, &showlist);
-  add_prefix_cmd ("tdesc", class_maintenance, unset_tdesc_cmd, _("\
+                      &tdesc_show_cmdlist, "show tdesc ",
+                      0 /* allow-unknown */, &showlist);
+  add_basic_prefix_cmd ("tdesc", class_maintenance, _("\
 Unset target description specific variables."),
-                 &tdesc_unset_cmdlist, "unset tdesc ",
-                 0 /* allow-unknown */, &unsetlist);
+                       &tdesc_unset_cmdlist, "unset tdesc ",
+                       0 /* allow-unknown */, &unsetlist);
 
   add_setshow_filename_cmd ("filename", class_obscure,
                            &tdesc_filename_cmd_string,
                            _("\
-Set the file to read for an XML target description"), _("\
-Show the file to read for an XML target description"), _("\
+Set the file to read for an XML target description."), _("\
+Show the file to read for an XML target description."), _("\
 When set, GDB will read the target description from a local\n\
 file instead of querying the remote target."),
                            set_tdesc_filename_cmd,
@@ -2185,18 +1953,23 @@ file instead of querying the remote target."),
                            &tdesc_set_cmdlist, &tdesc_show_cmdlist);
 
   add_cmd ("filename", class_obscure, unset_tdesc_filename_cmd, _("\
-Unset the file to read for an XML target description.  When unset,\n\
-GDB will read the description from the target."),
+Unset the file to read for an XML target description.\n\
+When unset, GDB will read the description from the target."),
           &tdesc_unset_cmdlist);
 
-  add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\
+  cmd = add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\
 Print the current target description as a C source file."),
           &maintenanceprintlist);
+  set_cmd_completer (cmd, filename_completer);
 
-  cmd_list_element *cmd;
+  cmd = add_cmd ("xml-tdesc", class_maintenance, maint_print_xml_tdesc_cmd, _("\
+Print the current target description as an XML file."),
+                &maintenanceprintlist);
+  set_cmd_completer (cmd, filename_completer);
 
   cmd = add_cmd ("xml-descriptions", class_maintenance,
                 maintenance_check_xml_descriptions, _("\
+Check equality of GDB target descriptions and XML created descriptions.\n\
 Check the target descriptions created in GDB equal the descriptions\n\
 created from XML files in the directory.\n\
 The parameter is the directory name."),
This page took 0.047021 seconds and 4 git commands to generate.