/* Target description support for GDB.

   Copyright (C) 2006-2021 Free Software Foundation, Inc.

   Contributed by CodeSourcery.

   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/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "gdbcmd.h"
#include "gdbtypes.h"
#include "reggroups.h"
#include "target.h"
#include "target-descriptions.h"
#include "xml-support.h"
#include "xml-tdesc.h"
#include "osabi.h"

#include "gdb_obstack.h"
#include "hashtab.h"
#include "inferior.h"
#include <algorithm>
#include "completer.h"
#include "readline/tilde.h" /* tilde_expand */

/* Types.  */

struct property
{
  property (const std::string &key_, const std::string &value_)
  : key (key_), value (value_)
  {}

  std::string key;
  std::string value;
};

/* Convert a tdesc_type to a gdb type.  */

static type *
make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
{
  class gdb_type_creator : public tdesc_element_visitor
  {
  public:
    gdb_type_creator (struct gdbarch *gdbarch)
      : m_gdbarch (gdbarch)
    {}

    type *get_type ()
    {
      return m_type;
    }

    void visit (const tdesc_type_builtin *e) override
    {
      switch (e->kind)
	{
	  /* Predefined types.  */
	case TDESC_TYPE_BOOL:
	  m_type = builtin_type (m_gdbarch)->builtin_bool;
	  return;
	case TDESC_TYPE_INT8:
	  m_type = builtin_type (m_gdbarch)->builtin_int8;
	  return;
	case TDESC_TYPE_INT16:
	  m_type = builtin_type (m_gdbarch)->builtin_int16;
	  return;
	case TDESC_TYPE_INT32:
	  m_type = builtin_type (m_gdbarch)->builtin_int32;
	  return;
	case TDESC_TYPE_INT64:
	  m_type = builtin_type (m_gdbarch)->builtin_int64;
	  return;
	case TDESC_TYPE_INT128:
	  m_type = builtin_type (m_gdbarch)->builtin_int128;
	  return;
	case TDESC_TYPE_UINT8:
	  m_type = builtin_type (m_gdbarch)->builtin_uint8;
	  return;
	case TDESC_TYPE_UINT16:
	  m_type = builtin_type (m_gdbarch)->builtin_uint16;
	  return;
	case TDESC_TYPE_UINT32:
	  m_type = builtin_type (m_gdbarch)->builtin_uint32;
	  return;
	case TDESC_TYPE_UINT64:
	  m_type = builtin_type (m_gdbarch)->builtin_uint64;
	  return;
	case TDESC_TYPE_UINT128:
	  m_type = builtin_type (m_gdbarch)->builtin_uint128;
	  return;
	case TDESC_TYPE_CODE_PTR:
	  m_type = builtin_type (m_gdbarch)->builtin_func_ptr;
	  return;
	case TDESC_TYPE_DATA_PTR:
	  m_type = builtin_type (m_gdbarch)->builtin_data_ptr;
	  return;
	}

      m_type = tdesc_find_type (m_gdbarch, e->name.c_str ());
      if (m_type != NULL)
	return;

      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);
	  return;

	case TDESC_TYPE_IEEE_DOUBLE:
	  m_type = arch_float_type (m_gdbarch, -1, "builtin_type_ieee_double",
				    floatformats_ieee_double);
	  return;
	case TDESC_TYPE_ARM_FPA_EXT:
	  m_type = arch_float_type (m_gdbarch, -1, "builtin_type_arm_ext",
				    floatformats_arm_ext);
	  return;

	case TDESC_TYPE_I387_EXT:
	  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__,
		      "Type \"%s\" has an unknown kind %d",
		      e->name.c_str (), e->kind);
    }

    void visit (const tdesc_type_vector *e) override
    {
      m_type = tdesc_find_type (m_gdbarch, e->name.c_str ());
      if (m_type != NULL)
	return;

      type *element_gdb_type = make_gdb_type (m_gdbarch, e->element_type);
      m_type = init_vector_type (element_gdb_type, e->count);
      m_type->set_name (xstrdup (e->name.c_str ()));
      return;
    }

    void visit (const tdesc_type_with_fields *e) override
    {
      m_type = tdesc_find_type (m_gdbarch, e->name.c_str ());
      if (m_type != NULL)
	return;

      switch (e->kind)
	{
	case TDESC_TYPE_STRUCT:
	  make_gdb_type_struct (e);
	  return;
	case TDESC_TYPE_UNION:
	  make_gdb_type_union (e);
	  return;
	case TDESC_TYPE_FLAGS:
	  make_gdb_type_flags (e);
	  return;
	case TDESC_TYPE_ENUM:
	  make_gdb_type_enum (e);
	  return;
	}

      internal_error (__FILE__, __LINE__,
		      "Type \"%s\" has an unknown kind %d",
		      e->name.c_str (), e->kind);
    }

  private:

    void make_gdb_type_struct (const tdesc_type_with_fields *e)
    {
      m_type = arch_composite_type (m_gdbarch, NULL, TYPE_CODE_STRUCT);
      m_type->set_name (xstrdup (e->name.c_str ()));

      for (const tdesc_type_field &f : e->fields)
	{
	  if (f.start != -1 && f.end != -1)
	    {
	      /* Bitfield.  */
	      struct field *fld;
	      struct type *field_gdb_type;
	      int bitsize, total_size;

	      /* This invariant should be preserved while creating types.  */
	      gdb_assert (e->size != 0);
	      if (f.type != NULL)
		field_gdb_type = make_gdb_type (m_gdbarch, f.type);
	      else if (e->size > 4)
		field_gdb_type = builtin_type (m_gdbarch)->builtin_uint64;
	      else
		field_gdb_type = builtin_type (m_gdbarch)->builtin_uint32;

	      fld = append_composite_type_field_raw
		      (m_type, xstrdup (f.name.c_str ()), field_gdb_type);

	      /* For little-endian, BITPOS counts from the LSB of
		 the structure and marks the LSB of the field.  For
		 big-endian, BITPOS counts from the MSB of the
		 structure and marks the MSB of the field.  Either
		 way, it is the number of bits to the "left" of the
		 field.  To calculate this in big-endian, we need
		 the total size of the structure.  */
	      bitsize = f.end - f.start + 1;
	      total_size = e->size * TARGET_CHAR_BIT;
	      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);
	      FIELD_BITSIZE (fld[0]) = bitsize;
	    }
	  else
	    {
	      gdb_assert (f.start == -1 && f.end == -1);
	      type *field_gdb_type = make_gdb_type (m_gdbarch, f.type);
	      append_composite_type_field (m_type,
					   xstrdup (f.name.c_str ()),
					   field_gdb_type);
	    }
	}

      if (e->size != 0)
	TYPE_LENGTH (m_type) = e->size;
    }

    void make_gdb_type_union (const tdesc_type_with_fields *e)
    {
      m_type = arch_composite_type (m_gdbarch, NULL, TYPE_CODE_UNION);
      m_type->set_name (xstrdup (e->name.c_str ()));

      for (const tdesc_type_field &f : e->fields)
	{
	  type* field_gdb_type = make_gdb_type (m_gdbarch, f.type);
	  append_composite_type_field (m_type, xstrdup (f.name.c_str ()),
				       field_gdb_type);

	  /* If any of the children of a union are vectors, flag the
	     union as a vector also.  This allows e.g. a union of two
	     vector types to show up automatically in "info vector".  */
	  if (field_gdb_type->is_vector ())
	    m_type->set_is_vector (true);
	}
    }

    void make_gdb_type_flags (const tdesc_type_with_fields *e)
    {
      m_type = arch_flags_type (m_gdbarch, e->name.c_str (),
				e->size * TARGET_CHAR_BIT);

      for (const tdesc_type_field &f : e->fields)
	{
	  int bitsize = f.end - f.start + 1;

	  gdb_assert (f.type != NULL);
	  type *field_gdb_type = make_gdb_type (m_gdbarch, f.type);
	  append_flags_type_field (m_type, f.start, bitsize,
				   field_gdb_type, f.name.c_str ());
	}
    }

    void make_gdb_type_enum (const tdesc_type_with_fields *e)
    {
      m_type = arch_type (m_gdbarch, TYPE_CODE_ENUM, e->size * TARGET_CHAR_BIT,
			  e->name.c_str ());

      m_type->set_is_unsigned (true);

      for (const tdesc_type_field &f : e->fields)
	{
	  struct field *fld
	    = append_composite_type_field_raw (m_type,
					       xstrdup (f.name.c_str ()),
					       NULL);

	  SET_FIELD_BITPOS (fld[0], f.start);
	}
    }

    /* The gdbarch used.  */
    struct gdbarch *m_gdbarch;

    /* The type created.  */
    type *m_type;
  };

  gdb_type_creator gdb_type (gdbarch);
  ttype->accept (gdb_type);
  return gdb_type.get_type ();
}

/* 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.  */

class tdesc_compatible_info
{
public:
  /* Constructor.  */
  explicit tdesc_compatible_info (const bfd_arch_info_type *arch)
    : m_arch (arch)
  { /* Nothing.  */ }

  /* Access the contained pointer.  */
  const bfd_arch_info_type *arch () const
  { return m_arch; }

private:
  /* Architecture information looked up from the <compatible> entity within
     a target description.  */
  const bfd_arch_info_type *m_arch;
};

/* A target description.  */

struct target_desc : tdesc_element
{
  target_desc ()
  {}

  virtual ~target_desc () = default;

  target_desc (const target_desc &) = delete;
  void operator= (const target_desc &) = delete;

  /* The architecture reported by the target, if any.  */
  const struct bfd_arch_info *arch = NULL;

  /* The osabi reported by the target, if any; GDB_OSABI_UNKNOWN
     otherwise.  */
  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;

  /* The list of compatible architectures reported by the target.  */
  std::vector<tdesc_compatible_info_up> compatible;

  /* Any architecture-specific properties specified by the target.  */
  std::vector<property> properties;

  /* 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);

    for (const tdesc_feature_up &feature : features)
      feature->accept (v);

    v.visit_post (this);
  }

  bool operator== (const target_desc &other) const
  {
    if (arch != other.arch)
      return false;

    if (osabi != other.osabi)
      return false;

    if (features.size () != other.features.size ())
      return false;

    for (int ix = 0; ix < features.size (); ix++)
      {
	const tdesc_feature_up &feature1 = features[ix];
	const tdesc_feature_up &feature2 = other.features[ix];

	if (feature1 != feature2 && *feature1 != *feature2)
	  return false;
      }

    return true;
  }

  bool operator!= (const target_desc &other) const
  {
    return !(*this == other);
  }
};

/* Per-architecture data associated with a target description.  The
   target description may be shared by multiple architectures, but
   this data is private to one gdbarch.  */

struct tdesc_arch_reg
{
  tdesc_arch_reg (tdesc_reg *reg_, struct type *type_)
  : reg (reg_), type (type_)
  {}

  struct tdesc_reg *reg;
  struct type *type;
};

struct tdesc_arch_data
{
  /* A list of register/type pairs, indexed by GDB's internal register number.
     During initialization of the gdbarch this list is used to store
     registers which the architecture assigns a fixed register number.
     Registers which are NULL in this array, or off the end, are
     treated as zero-sized and nameless (i.e. placeholders in the
     numbering).  */
  std::vector<tdesc_arch_reg> arch_regs;

  /* Functions which report the register name, type, and reggroups for
     pseudo-registers.  */
  gdbarch_register_name_ftype *pseudo_register_name = NULL;
  gdbarch_register_type_ftype *pseudo_register_type = NULL;
  gdbarch_register_reggroup_p_ftype *pseudo_register_reggroup_p = NULL;
};

/* Info about an inferior's target description.  There's one of these
   for each inferior.  */

struct target_desc_info
{
  /* A flag indicating that a description has already been fetched
     from the target, so it should not be queried again.  */

  bool fetched = false;

  /* The description fetched from the target, or NULL if the target
     did not supply any description.  Only valid when
     FETCHED is set.  Only the description initialization
     code should access this; normally, the description should be
     accessed through the gdbarch object.  */

  const struct target_desc *tdesc = nullptr;

  /* If not empty, the filename to read a target description from, as set by
     "set tdesc filename ...".

     If empty, there is not filename specified by the user.  */

  std::string filename;
};

/* Get the inferior INF's target description info, allocating one on
   the stop if necessary.  */

static struct target_desc_info *
get_tdesc_info (struct inferior *inf)
{
  if (inf->tdesc_info == NULL)
    inf->tdesc_info = new target_desc_info;

  return inf->tdesc_info;
}

/* A handle for architecture-specific data associated with the
   target description (see struct tdesc_arch_data).  */

static struct gdbarch_data *tdesc_data;

/* See target-descriptions.h.  */

int
target_desc_info_from_user_p (struct target_desc_info *info)
{
  return info != nullptr && !info->filename.empty ();
}

/* See target-descriptions.h.  */

void
copy_inferior_target_desc_info (struct inferior *destinf, struct inferior *srcinf)
{
  struct target_desc_info *src = get_tdesc_info (srcinf);
  struct target_desc_info *dest = get_tdesc_info (destinf);

  *dest = *src;
}

/* See target-descriptions.h.  */

void
target_desc_info_free (struct target_desc_info *tdesc_info)
{
  delete tdesc_info;
}

/* The string manipulated by the "set tdesc filename ..." command.  */

static char *tdesc_filename_cmd_string;

/* Fetch the current target's description, and switch the current
   architecture to one which incorporates that description.  */

void
target_find_description (void)
{
  target_desc_info *tdesc_info = get_tdesc_info (current_inferior ());

  /* If we've already fetched a description from the target, don't do
     it again.  This allows a target to fetch the description early,
     during its to_open or to_create_inferior, if it needs extra
     information about the target to initialize.  */
  if (tdesc_info->fetched)
    return;

  /* The current architecture should not have any target description
     specified.  It should have been cleared, e.g. when we
     disconnected from the previous target.  */
  gdb_assert (gdbarch_target_desc (target_gdbarch ()) == NULL);

  /* First try to fetch an XML description from the user-specified
     file.  */
  tdesc_info->tdesc = nullptr;
  if (!tdesc_info->filename.empty ())
    tdesc_info->tdesc = file_read_description_xml (tdesc_info->filename.data ());

  /* Next try to read the description from the current target using
     target objects.  */
  if (tdesc_info->tdesc == nullptr)
    tdesc_info->tdesc = target_read_description_xml
      (current_inferior ()->top_target ());

  /* If that failed try a target-specific hook.  */
  if (tdesc_info->tdesc == nullptr)
    tdesc_info->tdesc = target_read_description
      (current_inferior ()->top_target ());

  /* If a non-NULL description was returned, then update the current
     architecture.  */
  if (tdesc_info->tdesc != nullptr)
    {
      struct gdbarch_info info;

      info.target_desc = tdesc_info->tdesc;
      if (!gdbarch_update_p (info))
	warning (_("Architecture rejected target-supplied description"));
      else
	{
	  struct tdesc_arch_data *data;

	  data = ((struct tdesc_arch_data *)
		  gdbarch_data (target_gdbarch (), tdesc_data));
	  if (tdesc_has_registers (tdesc_info->tdesc)
	      && data->arch_regs.empty ())
	    warning (_("Target-supplied registers are not supported "
		       "by the current architecture"));
	}
    }

  /* Now that we know this description is usable, record that we
     fetched it.  */
  tdesc_info->fetched = true;
}

/* Discard any description fetched from the current target, and switch
   the current architecture to one with no target description.  */

void
target_clear_description (void)
{
  target_desc_info *tdesc_info = get_tdesc_info (current_inferior ());

  if (!tdesc_info->fetched)
    return;

  tdesc_info->fetched = false;
  tdesc_info->tdesc = nullptr;

  gdbarch_info info;
  if (!gdbarch_update_p (info))
    internal_error (__FILE__, __LINE__,
		    _("Could not remove target-supplied description"));
}

/* Return the global current target description.  This should only be
   used by gdbarch initialization code; most access should be through
   an existing gdbarch.  */

const struct target_desc *
target_current_description (void)
{
  target_desc_info *tdesc_info = get_tdesc_info (current_inferior ());

  if (tdesc_info->fetched)
    return tdesc_info->tdesc;

  return NULL;
}

/* Return non-zero if this target description is compatible
   with the given BFD architecture.  */

int
tdesc_compatible_p (const struct target_desc *target_desc,
		    const struct bfd_arch_info *arch)
{
  for (const tdesc_compatible_info_up &compat : target_desc->compatible)
    {
      if (compat->arch () == arch
	  || arch->compatible (arch, compat->arch ())
	  || compat->arch ()->compatible (compat->arch (), arch))
	return 1;
    }

  return 0;
}


/* Direct accessors for target descriptions.  */

/* Return the string value of a property named KEY, or NULL if the
   property was not specified.  */

const char *
tdesc_property (const struct target_desc *target_desc, const char *key)
{
  for (const property &prop : target_desc->properties)
    if (prop.key == key)
      return prop.value.c_str ();

  return NULL;
}

/* Return the BFD architecture associated with this target
   description, or NULL if no architecture was specified.  */

const struct bfd_arch_info *
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.  */

enum gdb_osabi
tdesc_osabi (const struct target_desc *target_desc)
{
  return target_desc->osabi;
}

/* 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.  */

int
tdesc_has_registers (const struct target_desc *target_desc)
{
  if (target_desc == NULL)
    return 0;

  for (const tdesc_feature_up &feature : target_desc->features)
    if (!feature->registers.empty ())
      return 1;

  return 0;
}

/* Return the feature with the given name, if present, or NULL if
   the named feature is not found.  */

const struct tdesc_feature *
tdesc_find_feature (const struct target_desc *target_desc,
		    const char *name)
{
  for (const tdesc_feature_up &feature : target_desc->features)
    if (feature->name == name)
      return feature.get ();

  return NULL;
}

/* Return the name of FEATURE.  */

const char *
tdesc_feature_name (const struct tdesc_feature *feature)
{
  return feature->name.c_str ();
}

/* Lookup type associated with ID.  */

struct type *
tdesc_find_type (struct gdbarch *gdbarch, const char *id)
{
  tdesc_arch_data *data
    = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

  for (const tdesc_arch_reg &reg : data->arch_regs)
    {
      if (reg.reg
	  && reg.reg->tdesc_type
	  && reg.type
	  && reg.reg->tdesc_type->name == id)
	return reg.type;
    }

  return NULL;
}

/* Support for registers from target descriptions.  */

/* Construct the per-gdbarch data.  */

static void *
tdesc_data_init (struct obstack *obstack)
{
  return obstack_new<tdesc_arch_data> (obstack);
}

/* Similar, but for the temporary copy used during architecture
   initialization.  */

tdesc_arch_data_up
tdesc_data_alloc (void)
{
  return tdesc_arch_data_up (new tdesc_arch_data ());
}

/* See target-descriptions.h.  */

void
tdesc_arch_data_deleter::operator() (struct tdesc_arch_data *data) const
{
  delete data;
}

/* Search FEATURE for a register named NAME.  */

static struct tdesc_reg *
tdesc_find_register_early (const struct tdesc_feature *feature,
			   const char *name)
{
  for (const tdesc_reg_up &reg : feature->registers)
    if (strcasecmp (reg->name.c_str (), name) == 0)
      return reg.get ();

  return NULL;
}

/* Search FEATURE for a register named NAME.  Assign REGNO to it.  */

int
tdesc_numbered_register (const struct tdesc_feature *feature,
			 struct tdesc_arch_data *data,
			 int regno, const char *name)
{
  struct tdesc_reg *reg = tdesc_find_register_early (feature, name);

  if (reg == NULL)
    return 0;

  /* Make sure the vector includes a REGNO'th element.  */
  while (regno >= data->arch_regs.size ())
    data->arch_regs.emplace_back (nullptr, nullptr);

  data->arch_regs[regno] = tdesc_arch_reg (reg, NULL);

  return 1;
}

/* Search FEATURE for a register named NAME, but do not assign a fixed
   register number to it.  */

int
tdesc_unnumbered_register (const struct tdesc_feature *feature,
			   const char *name)
{
  struct tdesc_reg *reg = tdesc_find_register_early (feature, name);

  if (reg == NULL)
    return 0;

  return 1;
}

/* Search FEATURE for a register whose name is in NAMES and assign
   REGNO to it.  */

int
tdesc_numbered_register_choices (const struct tdesc_feature *feature,
				 struct tdesc_arch_data *data,
				 int regno, const char *const names[])
{
  int i;

  for (i = 0; names[i] != NULL; i++)
    if (tdesc_numbered_register (feature, data, regno, names[i]))
      return 1;

  return 0;
}

/* Search FEATURE for a register named NAME, and return its size in
   bits.  The register must exist.  */

int
tdesc_register_bitsize (const struct tdesc_feature *feature, const char *name)
{
  struct tdesc_reg *reg = tdesc_find_register_early (feature, name);

  gdb_assert (reg != NULL);
  return reg->bitsize;
}

/* Look up a register by its GDB internal register number.  */

static struct tdesc_arch_reg *
tdesc_find_arch_register (struct gdbarch *gdbarch, int regno)
{
  struct tdesc_arch_data *data;

  data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
  if (regno < data->arch_regs.size ())
    return &data->arch_regs[regno];
  else
    return NULL;
}

static struct tdesc_reg *
tdesc_find_register (struct gdbarch *gdbarch, int regno)
{
  struct tdesc_arch_reg *reg = tdesc_find_arch_register (gdbarch, regno);

  return reg? reg->reg : NULL;
}

/* Return the name of register REGNO, from the target description or
   from an architecture-provided pseudo_register_name method.  */

const char *
tdesc_register_name (struct gdbarch *gdbarch, int regno)
{
  struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
  int num_regs = gdbarch_num_regs (gdbarch);

  if (reg != NULL)
    return reg->name.c_str ();

  if (regno >= num_regs && regno < gdbarch_num_cooked_regs (gdbarch))
    {
      struct tdesc_arch_data *data
	= (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

      gdb_assert (data->pseudo_register_name != NULL);
      return data->pseudo_register_name (gdbarch, regno);
    }

  return "";
}

struct type *
tdesc_register_type (struct gdbarch *gdbarch, int regno)
{
  struct tdesc_arch_reg *arch_reg = tdesc_find_arch_register (gdbarch, regno);
  struct tdesc_reg *reg = arch_reg? arch_reg->reg : NULL;
  int num_regs = gdbarch_num_regs (gdbarch);
  int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);

  if (reg == NULL && regno >= num_regs && regno < num_regs + num_pseudo_regs)
    {
      struct tdesc_arch_data *data
	= (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

      gdb_assert (data->pseudo_register_type != NULL);
      return data->pseudo_register_type (gdbarch, regno);
    }

  if (reg == NULL)
    /* Return "int0_t", since "void" has a misleading size of one.  */
    return builtin_type (gdbarch)->builtin_int0;

  if (arch_reg->type == NULL)
    {
      /* First check for a predefined or target defined type.  */
      if (reg->tdesc_type)
	arch_reg->type = make_gdb_type (gdbarch, reg->tdesc_type);

      /* Next try size-sensitive type shortcuts.  */
      else if (reg->type == "float")
	{
	  if (reg->bitsize == gdbarch_float_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_float;
	  else if (reg->bitsize == gdbarch_double_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_double;
	  else if (reg->bitsize == gdbarch_long_double_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_long_double;
	  else
	    {
	      warning (_("Register \"%s\" has an unsupported size (%d bits)"),
		       reg->name.c_str (), reg->bitsize);
	      arch_reg->type = builtin_type (gdbarch)->builtin_double;
	    }
	}
      else if (reg->type == "int")
	{
	  if (reg->bitsize == gdbarch_long_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_long;
	  else if (reg->bitsize == TARGET_CHAR_BIT)
	    arch_reg->type = builtin_type (gdbarch)->builtin_char;
	  else if (reg->bitsize == gdbarch_short_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_short;
	  else if (reg->bitsize == gdbarch_int_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_int;
	  else if (reg->bitsize == gdbarch_long_long_bit (gdbarch))
	    arch_reg->type = builtin_type (gdbarch)->builtin_long_long;
	  else if (reg->bitsize == gdbarch_ptr_bit (gdbarch))
	  /* A bit desperate by this point...  */
	    arch_reg->type = builtin_type (gdbarch)->builtin_data_ptr;
	  else
	    {
	      warning (_("Register \"%s\" has an unsupported size (%d bits)"),
		       reg->name.c_str (), reg->bitsize);
	      arch_reg->type = builtin_type (gdbarch)->builtin_long;
	    }
	}

      if (arch_reg->type == NULL)
	internal_error (__FILE__, __LINE__,
			"Register \"%s\" has an unknown type \"%s\"",
			reg->name.c_str (), reg->type.c_str ());
    }

  return arch_reg->type;
}

static int
tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
{
  struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);

  if (reg != NULL)
    return reg->target_regnum;
  else
    return -1;
}

/* Check whether REGNUM is a member of REGGROUP.  Registers from the
   target description may be classified as general, float, vector or other
   register groups registered with reggroup_add().  Unlike a gdbarch
   register_reggroup_p method, this function will return -1 if it does not
   know; the caller should handle registers with no specified group.

   The names of containing features are not used.  This might be extended
   to display registers in some more useful groupings.

   The save-restore flag is also implemented here.  */

int
tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
			      struct reggroup *reggroup)
{
  struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);

  if (reg != NULL && !reg->group.empty ()
      && (reg->group == reggroup_name (reggroup)))
	return 1;

  if (reg != NULL
      && (reggroup == save_reggroup || reggroup == restore_reggroup))
    return reg->save_restore;

  return -1;
}

/* Check whether REGNUM is a member of REGGROUP.  Registers with no
   group specified go to the default reggroup function and are handled
   by type.  */

static int
tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regno,
			   struct reggroup *reggroup)
{
  int num_regs = gdbarch_num_regs (gdbarch);
  int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);
  int ret;

  if (regno >= num_regs && regno < num_regs + num_pseudo_regs)
    {
      struct tdesc_arch_data *data
	= (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

      if (data->pseudo_register_reggroup_p != NULL)
	return data->pseudo_register_reggroup_p (gdbarch, regno, reggroup);
      /* Otherwise fall through to the default reggroup_p.  */
    }

  ret = tdesc_register_in_reggroup_p (gdbarch, regno, reggroup);
  if (ret != -1)
    return ret;

  return default_register_reggroup_p (gdbarch, regno, reggroup);
}

/* Record architecture-specific functions to call for pseudo-register
   support.  */

void
set_tdesc_pseudo_register_name (struct gdbarch *gdbarch,
				gdbarch_register_name_ftype *pseudo_name)
{
  struct tdesc_arch_data *data
    = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

  data->pseudo_register_name = pseudo_name;
}

void
set_tdesc_pseudo_register_type (struct gdbarch *gdbarch,
				gdbarch_register_type_ftype *pseudo_type)
{
  struct tdesc_arch_data *data
    = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

  data->pseudo_register_type = pseudo_type;
}

void
set_tdesc_pseudo_register_reggroup_p
  (struct gdbarch *gdbarch,
   gdbarch_register_reggroup_p_ftype *pseudo_reggroup_p)
{
  struct tdesc_arch_data *data
    = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

  data->pseudo_register_reggroup_p = pseudo_reggroup_p;
}

/* Update GDBARCH to use the target description for registers.  */

void
tdesc_use_registers (struct gdbarch *gdbarch,
		     const struct target_desc *target_desc,
		     tdesc_arch_data_up &&early_data,
		     tdesc_unknown_register_ftype unk_reg_cb)
{
  int num_regs = gdbarch_num_regs (gdbarch);
  struct tdesc_arch_data *data;

  /* We can't use the description for registers if it doesn't describe
     any.  This function should only be called after validating
     registers, so the caller should know that registers are
     included.  */
  gdb_assert (tdesc_has_registers (target_desc));

  data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
  data->arch_regs = std::move (early_data->arch_regs);

  /* Build up a set of all registers, so that we can assign register
     numbers where needed.  The hash table expands as necessary, so
     the initial size is arbitrary.  */
  htab_up reg_hash (htab_create (37, htab_hash_pointer, htab_eq_pointer,
				 NULL));
  for (const tdesc_feature_up &feature : target_desc->features)
    for (const tdesc_reg_up &reg : feature->registers)
      {
	void **slot = htab_find_slot (reg_hash.get (), reg.get (), INSERT);

	*slot = reg.get ();
	/* Add reggroup if its new.  */
	if (!reg->group.empty ())
	  if (reggroup_find (gdbarch, reg->group.c_str ()) == NULL)
	    reggroup_add (gdbarch, reggroup_gdbarch_new (gdbarch,
							 reg->group.c_str (),
							 USER_REGGROUP));
      }

  /* Remove any registers which were assigned numbers by the
     architecture.  */
  for (const tdesc_arch_reg &arch_reg : data->arch_regs)
    if (arch_reg.reg != NULL)
      htab_remove_elt (reg_hash.get (), arch_reg.reg);

  /* Assign numbers to the remaining registers and add them to the
     list of registers.  The new numbers are always above gdbarch_num_regs.
     Iterate over the features, not the hash table, so that the order
     matches that in the target description.  */

  gdb_assert (data->arch_regs.size () <= num_regs);
  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.get (), 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.get (), 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.get (), reg.get ()) != NULL)
	{
	  data->arch_regs.emplace_back (reg.get (), nullptr);
	  num_regs++;
	}

  /* Update the architecture.  */
  set_gdbarch_num_regs (gdbarch, num_regs);
  set_gdbarch_register_name (gdbarch, tdesc_register_name);
  set_gdbarch_register_type (gdbarch, tdesc_register_type);
  set_gdbarch_remote_register_number (gdbarch,
				      tdesc_remote_register_number);
  set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p);
}

/* See gdbsupport/tdesc.h.  */

struct tdesc_feature *
tdesc_create_feature (struct target_desc *tdesc, const char *name)
{
  struct tdesc_feature *new_feature = new tdesc_feature (name);

  tdesc->features.emplace_back (new_feature);

  return new_feature;
}

/* See gdbsupport/tdesc.h.  */

target_desc_up
allocate_target_description (void)
{
  return target_desc_up (new target_desc ());
}

/* See gdbsupport/tdesc.h.  */

void
target_desc_deleter::operator() (struct target_desc *target_desc) const
{
  delete target_desc;
}

void
tdesc_add_compatible (struct target_desc *target_desc,
		      const struct bfd_arch_info *compatible)
{
  /* If this instance of GDB is compiled without BFD support for the
     compatible architecture, simply ignore it -- we would not be able
     to handle it anyway.  */
  if (compatible == NULL)
    return;

  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
    (std::unique_ptr<tdesc_compatible_info>
     (new tdesc_compatible_info (compatible)));
}

void
set_tdesc_property (struct target_desc *target_desc,
		    const char *key, const char *value)
{
  gdb_assert (key != NULL && value != NULL);

  if (tdesc_property (target_desc, key) != NULL)
    internal_error (__FILE__, __LINE__,
		    _("Attempted to add duplicate property \"%s\""), key);

  target_desc->properties.emplace_back (key, value);
}

/* See gdbsupport/tdesc.h.  */

void
set_tdesc_architecture (struct target_desc *target_desc,
			const char *name)
{
  set_tdesc_architecture (target_desc, bfd_scan_arch (name));
}

void
set_tdesc_architecture (struct target_desc *target_desc,
			const struct bfd_arch_info *arch)
{
  target_desc->arch = arch;
}

/* See gdbsupport/tdesc.h.  */

void
set_tdesc_osabi (struct target_desc *target_desc, const char *name)
{
  set_tdesc_osabi (target_desc, osabi_from_tdesc_string (name));
}

void
set_tdesc_osabi (struct target_desc *target_desc, enum gdb_osabi osabi)
{
  target_desc->osabi = osabi;
}


static struct cmd_list_element *tdesc_set_cmdlist, *tdesc_show_cmdlist;
static struct cmd_list_element *tdesc_unset_cmdlist;

/* Helper functions for the CLI commands.  */

static void
set_tdesc_filename_cmd (const char *args, int from_tty,
			struct cmd_list_element *c)
{
  target_desc_info *tdesc_info = get_tdesc_info (current_inferior ());

  tdesc_info->filename = tdesc_filename_cmd_string;

  target_clear_description ();
  target_find_description ();
}

static void
show_tdesc_filename_cmd (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c,
			 const char *value)
{
  value = get_tdesc_info (current_inferior ())->filename.data ();

  if (value != NULL && *value != '\0')
    printf_filtered (_("The target description will be read from \"%s\".\n"),
		     value);
  else
    printf_filtered (_("The target description will be "
		       "read from the target.\n"));
}

static void
unset_tdesc_filename_cmd (const char *args, int from_tty)
{
  target_desc_info *tdesc_info = get_tdesc_info (current_inferior ());

  tdesc_info->filename.clear ();
  target_clear_description ();
  target_find_description ();
}

/* Print target description in C.  */

class print_c_tdesc : public tdesc_element_visitor
{
public:
  print_c_tdesc (std::string &filename_after_features)
    : m_filename_after_features (filename_after_features)
  {
    const char *inp;
    char *outp;
    const char *filename = lbasename (m_filename_after_features.c_str ());

    m_function = (char *) xmalloc (strlen (filename) + 1);
    for (inp = filename, outp = m_function; *inp != '\0'; inp++)
      if (*inp == '.')
	break;
      else if (*inp == '-')
	*outp++ = '_';
      else if (*inp == ' ')
	*outp++ = '_';
      else
	*outp++ = *inp;
    *outp = '\0';

    /* Standard boilerplate.  */
    printf_unfiltered ("/* THIS FILE IS GENERATED.  "
		       "-*- buffer-read-only: t -*- vi"
		       ":set ro:\n");
  }

  ~print_c_tdesc ()
  {
    xfree (m_function);
  }

  void visit_pre (const target_desc *e) override
  {
    printf_unfiltered ("  Original: %s */\n\n",
		       lbasename (m_filename_after_features.c_str ()));

    printf_unfiltered ("#include \"defs.h\"\n");
    printf_unfiltered ("#include \"osabi.h\"\n");
    printf_unfiltered ("#include \"target-descriptions.h\"\n");
    printf_unfiltered ("\n");

    printf_unfiltered ("struct target_desc *tdesc_%s;\n", m_function);
    printf_unfiltered ("static void\n");
    printf_unfiltered ("initialize_tdesc_%s (void)\n", m_function);
    printf_unfiltered ("{\n");
    printf_unfiltered
      ("  target_desc_up result = allocate_target_description ();\n");

    if (tdesc_architecture (e) != NULL)
      {
	printf_unfiltered
	  ("  set_tdesc_architecture (result.get (), bfd_scan_arch (\"%s\"));\n",
	   tdesc_architecture (e)->printable_name);
	printf_unfiltered ("\n");
      }
    if (tdesc_osabi (e) > GDB_OSABI_UNKNOWN
	&& tdesc_osabi (e) < GDB_OSABI_INVALID)
      {
	printf_unfiltered
	  ("  set_tdesc_osabi (result.get (), osabi_from_tdesc_string (\"%s\"));\n",
	   gdbarch_osabi_name (tdesc_osabi (e)));
	printf_unfiltered ("\n");
      }

    for (const tdesc_compatible_info_up &compatible : e->compatible)
      printf_unfiltered
	("  tdesc_add_compatible (result.get (), bfd_scan_arch (\"%s\"));\n",
	 compatible->arch ()->printable_name);

    if (!e->compatible.empty ())
      printf_unfiltered ("\n");

    for (const property &prop : e->properties)
      printf_unfiltered ("  set_tdesc_property (result.get (), \"%s\", \"%s\");\n",
			 prop.key.c_str (), prop.value.c_str ());

    printf_unfiltered ("  struct tdesc_feature *feature;\n");
  }

  void visit_pre (const tdesc_feature *e) override
  {
    printf_unfiltered ("\n  feature = tdesc_create_feature (result.get (), \"%s\");\n",
		       e->name.c_str ());
  }

  void visit_post (const tdesc_feature *e) override
  {}

  void visit_post (const target_desc *e) override
  {
    printf_unfiltered ("\n  tdesc_%s = result.release ();\n", m_function);
    printf_unfiltered ("}\n");
  }

  void visit (const tdesc_type_builtin *type) override
  {
    error (_("C output is not supported type \"%s\"."), type->name.c_str ());
  }

  void visit (const tdesc_type_vector *type) override
  {
    if (!m_printed_element_type)
      {
	printf_unfiltered ("  tdesc_type *element_type;\n");
	m_printed_element_type = true;
      }

    printf_unfiltered
      ("  element_type = tdesc_named_type (feature, \"%s\");\n",
       type->element_type->name.c_str ());
    printf_unfiltered
      ("  tdesc_create_vector (feature, \"%s\", element_type, %d);\n",
       type->name.c_str (), type->count);

    printf_unfiltered ("\n");
  }

  void visit (const tdesc_type_with_fields *type) override
  {
    if (!m_printed_type_with_fields)
      {
	printf_unfiltered ("  tdesc_type_with_fields *type_with_fields;\n");
	m_printed_type_with_fields = true;
      }

    switch (type->kind)
      {
      case TDESC_TYPE_STRUCT:
      case TDESC_TYPE_FLAGS:
	if (type->kind == TDESC_TYPE_STRUCT)
	  {
	    printf_unfiltered
	      ("  type_with_fields = tdesc_create_struct (feature, \"%s\");\n",
	       type->name.c_str ());
	    if (type->size != 0)
	      printf_unfiltered
		("  tdesc_set_struct_size (type_with_fields, %d);\n", type->size);
	  }
	else
	  {
	    printf_unfiltered
	      ("  type_with_fields = tdesc_create_flags (feature, \"%s\", %d);\n",
	       type->name.c_str (), type->size);
	  }
	for (const tdesc_type_field &f : type->fields)
	  {
	    const char *type_name;

	    gdb_assert (f.type != NULL);
	    type_name = f.type->name.c_str ();

	    /* To minimize changes to generated files, don't emit type
	       info for fields that have defaulted types.  */
	    if (f.start != -1)
	      {
		gdb_assert (f.end != -1);
		if (f.type->kind == TDESC_TYPE_BOOL)
		  {
		    gdb_assert (f.start == f.end);
		    printf_unfiltered
		      ("  tdesc_add_flag (type_with_fields, %d, \"%s\");\n",
		       f.start, f.name.c_str ());
		  }
		else if ((type->size == 4 && f.type->kind == TDESC_TYPE_UINT32)
			 || (type->size == 8
			     && f.type->kind == TDESC_TYPE_UINT64))
		  {
		    printf_unfiltered
		      ("  tdesc_add_bitfield (type_with_fields, \"%s\", %d, %d);\n",
		       f.name.c_str (), f.start, f.end);
		  }
		else
		  {
		    printf_field_type_assignment
		      ("tdesc_named_type (feature, \"%s\");\n",
		       type_name);
		    printf_unfiltered
		      ("  tdesc_add_typed_bitfield (type_with_fields, \"%s\","
		       " %d, %d, field_type);\n",
		       f.name.c_str (), f.start, f.end);
		  }
	      }
	    else /* Not a bitfield.  */
	      {
		gdb_assert (f.end == -1);
		gdb_assert (type->kind == TDESC_TYPE_STRUCT);
		printf_field_type_assignment
		  ("tdesc_named_type (feature, \"%s\");\n", type_name);
		printf_unfiltered
		  ("  tdesc_add_field (type_with_fields, \"%s\", field_type);\n",
		   f.name.c_str ());
	      }
	  }
	break;
      case TDESC_TYPE_UNION:
	printf_unfiltered
	  ("  type_with_fields = tdesc_create_union (feature, \"%s\");\n",
	   type->name.c_str ());
	for (const tdesc_type_field &f : type->fields)
	  {
	    printf_field_type_assignment
	      ("tdesc_named_type (feature, \"%s\");\n", f.type->name.c_str ());
	    printf_unfiltered
	      ("  tdesc_add_field (type_with_fields, \"%s\", field_type);\n",
	       f.name.c_str ());
	  }
	break;
      case TDESC_TYPE_ENUM:
	printf_unfiltered
	  ("  type_with_fields = tdesc_create_enum (feature, \"%s\", %d);\n",
	   type->name.c_str (), type->size);
	for (const tdesc_type_field &f : type->fields)
	  printf_unfiltered
	    ("  tdesc_add_enum_value (type_with_fields, %d, \"%s\");\n",
	     f.start, f.name.c_str ());
	break;
      default:
	error (_("C output is not supported type \"%s\"."), type->name.c_str ());
      }

    printf_unfiltered ("\n");
  }

  void visit (const tdesc_reg *reg) override
  {
    printf_unfiltered ("  tdesc_create_reg (feature, \"%s\", %ld, %d, ",
		       reg->name.c_str (), reg->target_regnum,
		       reg->save_restore);
    if (!reg->group.empty ())
      printf_unfiltered ("\"%s\", ", reg->group.c_str ());
    else
      printf_unfiltered ("NULL, ");
    printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type.c_str ());
  }

protected:
  std::string m_filename_after_features;

private:

  /* Print an assignment to the field_type variable.  Print the declaration
     of field_type if that has not been done yet.  */
  ATTRIBUTE_PRINTF (2, 3)
  void printf_field_type_assignment (const char *fmt, ...)
  {
    if (!m_printed_field_type)
      {
	printf_unfiltered ("  tdesc_type *field_type;\n");
	m_printed_field_type = true;
      }

    printf_unfiltered ("  field_type = ");

    va_list args;
    va_start (args, fmt);
    vprintf_unfiltered (fmt, args);
    va_end (args);
  }

  char *m_function;

  /* Did we print "struct tdesc_type *element_type;" yet?  */
  bool m_printed_element_type = false;

  /* Did we print "struct tdesc_type_with_fields *element_type;" yet?  */
  bool m_printed_type_with_fields = false;

  /* Did we print "struct tdesc_type *field_type;" yet?  */
  bool m_printed_field_type = false;
};

/* Print target description feature in C.  */

class print_c_feature : public print_c_tdesc
{
public:
  print_c_feature (std::string &file)
    : print_c_tdesc (file)
  {
    /* Trim ".tmp".  */
    auto const pos = m_filename_after_features.find_last_of ('.');

    m_filename_after_features = m_filename_after_features.substr (0, pos);
  }

  void visit_pre (const target_desc *e) override
  {
    printf_unfiltered ("  Original: %s */\n\n",
		       lbasename (m_filename_after_features.c_str ()));

    printf_unfiltered ("#include \"gdbsupport/tdesc.h\"\n");
    printf_unfiltered ("\n");
  }

  void visit_post (const target_desc *e) override
  {}

  void visit_pre (const tdesc_feature *e) override
  {
    std::string name (m_filename_after_features);

    auto pos = name.find_first_of ('.');

    name = name.substr (0, pos);
    std::replace (name.begin (), name.end (), '/', '_');
    std::replace (name.begin (), name.end (), '-', '_');

    printf_unfiltered ("static int\n");
    printf_unfiltered ("create_feature_%s ", name.c_str ());
    printf_unfiltered ("(struct target_desc *result, long regnum)\n");

    printf_unfiltered ("{\n");
    printf_unfiltered ("  struct tdesc_feature *feature;\n");

    printf_unfiltered
      ("\n  feature = tdesc_create_feature (result, \"%s\");\n",
       e->name.c_str ());
  }

  void visit_post (const tdesc_feature *e) override
  {
    printf_unfiltered ("  return regnum;\n");
    printf_unfiltered ("}\n");
  }

  void visit (const tdesc_reg *reg) override
  {
    /* Most "reg" in XML target descriptions don't have "regnum"
       attribute, so the register number is allocated sequentially.
       In case that reg has "regnum" attribute, register number
       should be set by that explicitly.  */

    if (reg->target_regnum < m_next_regnum)
      {
	/* The integrity check, it can catch some errors on register
	   number collision, like this,

	  <reg name="x0" bitsize="32"/>
	  <reg name="x1" bitsize="32"/>
	  <reg name="x2" bitsize="32"/>
	  <reg name="x3" bitsize="32"/>
	  <reg name="ps" bitsize="32" regnum="3"/>

	  but it also has false negatives.  The target description
	  below is correct,

	  <reg name="x1" bitsize="32" regnum="1"/>
	  <reg name="x3" bitsize="32" regnum="3"/>
	  <reg name="x2" bitsize="32" regnum="2"/>
	  <reg name="x4" bitsize="32" regnum="4"/>

	  but it is not a good practice, so still error on this,
	  and also print the message so that it can be saved in the
	  generated c file.  */

	printf_unfiltered ("ERROR: \"regnum\" attribute %ld ",
			   reg->target_regnum);
	printf_unfiltered ("is not the largest number (%d).\n",
			   m_next_regnum);
	error (_("\"regnum\" attribute %ld is not the largest number (%d)."),
	       reg->target_regnum, m_next_regnum);
      }

    if (reg->target_regnum > m_next_regnum)
      {
	printf_unfiltered ("  regnum = %ld;\n", reg->target_regnum);
	m_next_regnum = reg->target_regnum;
      }

    printf_unfiltered ("  tdesc_create_reg (feature, \"%s\", regnum++, %d, ",
		       reg->name.c_str (), reg->save_restore);
    if (!reg->group.empty ())
      printf_unfiltered ("\"%s\", ", reg->group.c_str ());
    else
      printf_unfiltered ("NULL, ");
    printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type.c_str ());

    m_next_regnum++;
  }

private:
  /* The register number to use for the next register we see.  */
  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;
}

/* Data structures and functions to setup the option flags for 'maintenance
   print c-tdesc command.  */

struct maint_print_c_tdesc_options
{
  /* True when the '-single-feature' flag was passed.  */
  bool single_feature = false;
};

using maint_print_c_tdesc_opt_def
  = gdb::option::flag_option_def<maint_print_c_tdesc_options>;

static const gdb::option::option_def maint_print_c_tdesc_opt_defs[] = {
  maint_print_c_tdesc_opt_def {
    "single-feature",
    [] (maint_print_c_tdesc_options *opt) { return &opt->single_feature; },
    N_("Print C description of just a single feature.")
  },
};

static inline gdb::option::option_def_group
make_maint_print_c_tdesc_options_def_group (maint_print_c_tdesc_options *opts)
{
  return {{maint_print_c_tdesc_opt_defs}, opts};
}

/* Implement 'maintenance print c-tdesc' command.  */

static void
maint_print_c_tdesc_cmd (const char *args, int from_tty)
{
  const struct target_desc *tdesc;
  const char *filename;

  maint_print_c_tdesc_options opts;
  auto grp = make_maint_print_c_tdesc_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);

  if (args == NULL)
    {
      /* Use the global target-supplied description, not the current
	 architecture's.  This lets a GDB for one architecture generate C
	 for another architecture's description, even though the gdbarch
	 initialization code will reject the new description.  */
      target_desc_info *tdesc_info = get_tdesc_info (current_inferior ());
      tdesc = tdesc_info->tdesc;
      filename = tdesc_info->filename.data ();
    }
  else
    {
      /* Use the target description from the XML file.  */
      filename = args;
      tdesc = file_read_description_xml (filename);
    }

  if (tdesc == NULL)
    error (_("There is no target description to print."));

  if (filename == NULL)
    filename = "fetched from target";

  std::string filename_after_features (filename);
  auto loc = filename_after_features.rfind ("/features/");

  if (loc != std::string::npos)
    filename_after_features = filename_after_features.substr (loc + 10);

  /* Print c files for target features instead of target descriptions,
     because c files got from target features are more flexible than the
     counterparts.  */
  if (opts.single_feature)
    {
      if (tdesc->features.size () != 1)
	error (_("only target descriptions with 1 feature can be used "
		 "with -single-feature option"));

      print_c_feature v (filename_after_features);

      tdesc->accept (v);
    }
  else
    {
      print_c_tdesc v (filename_after_features);

      tdesc->accept (v);
    }
}

/* Completer for the "backtrace" command.  */

static void
maint_print_c_tdesc_cmd_completer (struct cmd_list_element *ignore,
				   completion_tracker &tracker,
				   const char *text, const char *word)
{
  auto grp = make_maint_print_c_tdesc_options_def_group (nullptr);
  if (gdb::option::complete_options
      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
    return;

  word = advance_to_filename_complete_word_point (tracker, text);
  filename_completer (ignore, tracker, text, word);
}

/* 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 = get_tdesc_info (current_inferior ())->tdesc;
    }
  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 {

/* 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-descriptions.h.  */

void
record_xml_tdesc (const char *xml_file, const struct target_desc *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.  */

static void
maintenance_check_xml_descriptions (const char *dir, int from_tty)
{
  if (dir == NULL)
    error (_("Missing dir name"));

  gdb::unique_xmalloc_ptr<char> dir1 (tilde_expand (dir));
  std::string feature_dir (dir1.get ());
  unsigned int failed = 0;

  for (auto const &e : selftests::xml_tdesc)
    {
      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.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 ()
{
  cmd_list_element *cmd;

  tdesc_data = gdbarch_data_register_pre_init (tdesc_data_init);

  add_basic_prefix_cmd ("tdesc", class_maintenance, _("\
Set target description specific variables."),
			&tdesc_set_cmdlist,
			0 /* allow-unknown */, &setlist);
  add_show_prefix_cmd ("tdesc", class_maintenance, _("\
Show target description specific variables."),
		       &tdesc_show_cmdlist,
		       0 /* allow-unknown */, &showlist);
  add_basic_prefix_cmd ("tdesc", class_maintenance, _("\
Unset target description specific variables."),
			&tdesc_unset_cmdlist,
			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."), _("\
When set, GDB will read the target description from a local\n\
file instead of querying the remote target."),
			    set_tdesc_filename_cmd,
			    show_tdesc_filename_cmd,
			    &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.\n\
When unset, GDB will read the description from the target."),
	   &tdesc_unset_cmdlist);

  auto grp = make_maint_print_c_tdesc_options_def_group (nullptr);
  static std::string help_text
    = gdb::option::build_help (_("\
Print the current target description as a C source file.\n\
Usage: maintenance print c-tdesc [OPTION] [FILENAME]\n\
\n\
Options:\n\
%OPTIONS%\n\
\n\
When FILENAME is not provided then print the current target\n\
description, otherwise an XML target description is read from\n\
FILENAME and printed as a C function.\n\
\n\
When '-single-feature' is used then the target description should\n\
contain a single feature and the generated C code will only create\n\
that feature within an already existing target_desc object."), grp);
  cmd = add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd,
		 help_text.c_str (), &maintenanceprintlist);
  set_cmd_completer_handle_brkchars (cmd, maint_print_c_tdesc_cmd_completer);

  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."),
		 &maintenancechecklist);
  set_cmd_completer (cmd, filename_completer);
}
