/* Dynamic architecture support for GDB, the GNU debugger.

   Copyright (C) 1998-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"

#include "arch-utils.h"
#include "gdbcmd.h"
#include "inferior.h"		/* enum CALL_DUMMY_LOCATION et al.  */
#include "infrun.h"
#include "regcache.h"
#include "sim-regno.h"
#include "gdbcore.h"
#include "osabi.h"
#include "target-descriptions.h"
#include "objfiles.h"
#include "language.h"
#include "symtab.h"
#include "dummy-frame.h"
#include "frame-unwind.h"
#include "reggroups.h"
#include "auxv.h"
#include "observable.h"
#include "solib-target.h"

#include "gdbsupport/version.h"

#include "floatformat.h"

#include "dis-asm.h"

bool
default_displaced_step_hw_singlestep (struct gdbarch *gdbarch)
{
  return !gdbarch_software_single_step_p (gdbarch);
}

CORE_ADDR
displaced_step_at_entry_point (struct gdbarch *gdbarch)
{
  CORE_ADDR addr;
  int bp_len;

  addr = entry_point_address ();

  /* Inferior calls also use the entry point as a breakpoint location.
     We don't want displaced stepping to interfere with those
     breakpoints, so leave space.  */
  gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len);
  addr += bp_len * 2;

  return addr;
}

int
legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum)
{
  /* Only makes sense to supply raw registers.  */
  gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
  /* NOTE: cagney/2002-05-13: The old code did it this way and it is
     suspected that some GDB/SIM combinations may rely on this
     behaviour.  The default should be one2one_register_sim_regno
     (below).  */
  if (gdbarch_register_name (gdbarch, regnum)[0] != '\0')
    return regnum;
  else
    return LEGACY_SIM_REGNO_IGNORE;
}


/* See arch-utils.h */

std::string
default_memtag_to_string (struct gdbarch *gdbarch, struct value *tag)
{
  error (_("This architecture has no method to convert a memory tag to"
	   " a string."));
}

/* See arch-utils.h */

bool
default_tagged_address_p (struct gdbarch *gdbarch, struct value *address)
{
  /* By default, assume the address is untagged.  */
  return false;
}

/* See arch-utils.h */

bool
default_memtag_matches_p (struct gdbarch *gdbarch, struct value *address)
{
  /* By default, assume the tags match.  */
  return true;
}

/* See arch-utils.h */

bool
default_set_memtags (struct gdbarch *gdbarch, struct value *address,
		     size_t length, const gdb::byte_vector &tags,
		     memtag_type tag_type)
{
  /* By default, return true (successful);  */
  return true;
}

/* See arch-utils.h */

struct value *
default_get_memtag (struct gdbarch *gdbarch, struct value *address,
		    memtag_type tag_type)
{
  /* By default, return no tag.  */
  return nullptr;
}

CORE_ADDR
generic_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
{
  return 0;
}

CORE_ADDR
generic_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  return 0;
}

int
generic_in_solib_return_trampoline (struct gdbarch *gdbarch,
				    CORE_ADDR pc, const char *name)
{
  return 0;
}

int
generic_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  return 0;
}

int
default_code_of_frame_writable (struct gdbarch *gdbarch,
				frame_info_ptr frame)
{
  return 1;
}

/* Helper functions for gdbarch_inner_than */

int
core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs)
{
  return (lhs < rhs);
}

int
core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs)
{
  return (lhs > rhs);
}

/* Misc helper functions for targets.  */

CORE_ADDR
core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return addr;
}

CORE_ADDR
convert_from_func_ptr_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr,
				     struct target_ops *targ)
{
  return addr;
}

int
no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  return reg;
}

void
default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
{
  return;
}

/* See arch-utils.h.  */

void
default_make_symbol_special (struct symbol *sym, struct objfile *objfile)
{
  return;
}

/* See arch-utils.h.  */

CORE_ADDR
default_adjust_dwarf2_addr (CORE_ADDR pc)
{
  return pc;
}

/* See arch-utils.h.  */

CORE_ADDR
default_adjust_dwarf2_line (CORE_ADDR addr, int rel)
{
  return addr;
}

/* See arch-utils.h.  */

bool
default_execute_dwarf_cfa_vendor_op (struct gdbarch *gdbarch, gdb_byte op,
				     struct dwarf2_frame_state *fs)
{
  return false;
}

int
cannot_register_not (struct gdbarch *gdbarch, int regnum)
{
  return 0;
}

/* Legacy version of target_virtual_frame_pointer().  Assumes that
   there is an gdbarch_deprecated_fp_regnum and that it is the same,
   cooked or raw.  */

void
legacy_virtual_frame_pointer (struct gdbarch *gdbarch, 
			      CORE_ADDR pc,
			      int *frame_regnum,
			      LONGEST *frame_offset)
{
  /* FIXME: cagney/2002-09-13: This code is used when identifying the
     frame pointer of the current PC.  It is assuming that a single
     register and an offset can determine this.  I think it should
     instead generate a byte code expression as that would work better
     with things like Dwarf2's CFI.  */
  if (gdbarch_deprecated_fp_regnum (gdbarch) >= 0
      && gdbarch_deprecated_fp_regnum (gdbarch)
	   < gdbarch_num_regs (gdbarch))
    *frame_regnum = gdbarch_deprecated_fp_regnum (gdbarch);
  else if (gdbarch_sp_regnum (gdbarch) >= 0
	   && gdbarch_sp_regnum (gdbarch)
		< gdbarch_num_regs (gdbarch))
    *frame_regnum = gdbarch_sp_regnum (gdbarch);
  else
    /* Should this be an internal error?  I guess so, it is reflecting
       an architectural limitation in the current design.  */
    internal_error (__FILE__, __LINE__, 
		    _("No virtual frame pointer available"));
  *frame_offset = 0;
}

/* Return a floating-point format for a floating-point variable of
   length LEN in bits.  If non-NULL, NAME is the name of its type.
   If no suitable type is found, return NULL.  */

const struct floatformat **
default_floatformat_for_type (struct gdbarch *gdbarch,
			      const char *name, int len)
{
  const struct floatformat **format = NULL;

  /* Check if this is a bfloat16 type.  It has the same size as the
     IEEE half float type, so we use the base type name to tell them
     apart.  */
  if (name != nullptr && strcmp (name, "__bf16") == 0
      && len == gdbarch_bfloat16_bit (gdbarch))
    format = gdbarch_bfloat16_format (gdbarch);
  else if (len == gdbarch_half_bit (gdbarch))
    format = gdbarch_half_format (gdbarch);
  else if (len == gdbarch_float_bit (gdbarch))
    format = gdbarch_float_format (gdbarch);
  else if (len == gdbarch_double_bit (gdbarch))
    format = gdbarch_double_format (gdbarch);
  else if (len == gdbarch_long_double_bit (gdbarch))
    format = gdbarch_long_double_format (gdbarch);
  /* On i386 the 'long double' type takes 96 bits,
     while the real number of used bits is only 80,
     both in processor and in memory.
     The code below accepts the real bit size.  */
  else if (gdbarch_long_double_format (gdbarch) != NULL
	   && len == gdbarch_long_double_format (gdbarch)[0]->totalsize)
    format = gdbarch_long_double_format (gdbarch);

  return format;
}

int
generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
			    struct type *type)
{
  return 0;
}

int
default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
{
  return 0;
}

int
generic_instruction_nullified (struct gdbarch *gdbarch,
			       struct regcache *regcache)
{
  return 0;
}

int
default_remote_register_number (struct gdbarch *gdbarch,
				int regno)
{
  return regno;
}

/* See arch-utils.h.  */

int
default_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range)
{
  return 0;
}


/* Functions to manipulate the endianness of the target.  */

static enum bfd_endian target_byte_order_user = BFD_ENDIAN_UNKNOWN;

static const char endian_big[] = "big";
static const char endian_little[] = "little";
static const char endian_auto[] = "auto";
static const char *const endian_enum[] =
{
  endian_big,
  endian_little,
  endian_auto,
  NULL,
};
static const char *set_endian_string = endian_auto;

enum bfd_endian
selected_byte_order (void)
{
  return target_byte_order_user;
}

/* Called by ``show endian''.  */

static void
show_endian (struct ui_file *file, int from_tty, struct cmd_list_element *c,
	     const char *value)
{
  if (target_byte_order_user == BFD_ENDIAN_UNKNOWN)
    if (gdbarch_byte_order (get_current_arch ()) == BFD_ENDIAN_BIG)
      gdb_printf (file, _("The target endianness is set automatically "
			  "(currently big endian).\n"));
    else
      gdb_printf (file, _("The target endianness is set automatically "
			  "(currently little endian).\n"));
  else
    if (target_byte_order_user == BFD_ENDIAN_BIG)
      gdb_printf (file,
		  _("The target is set to big endian.\n"));
    else
      gdb_printf (file,
		  _("The target is set to little endian.\n"));
}

static void
set_endian (const char *ignore_args, int from_tty, struct cmd_list_element *c)
{
  struct gdbarch_info info;

  if (set_endian_string == endian_auto)
    {
      target_byte_order_user = BFD_ENDIAN_UNKNOWN;
      if (! gdbarch_update_p (info))
	internal_error (__FILE__, __LINE__,
			_("set_endian: architecture update failed"));
    }
  else if (set_endian_string == endian_little)
    {
      info.byte_order = BFD_ENDIAN_LITTLE;
      if (! gdbarch_update_p (info))
	gdb_printf (gdb_stderr,
		    _("Little endian target not supported by GDB\n"));
      else
	target_byte_order_user = BFD_ENDIAN_LITTLE;
    }
  else if (set_endian_string == endian_big)
    {
      info.byte_order = BFD_ENDIAN_BIG;
      if (! gdbarch_update_p (info))
	gdb_printf (gdb_stderr,
		    _("Big endian target not supported by GDB\n"));
      else
	target_byte_order_user = BFD_ENDIAN_BIG;
    }
  else
    internal_error (__FILE__, __LINE__,
		    _("set_endian: bad value"));

  show_endian (gdb_stdout, from_tty, NULL, NULL);
}

/* Given SELECTED, a currently selected BFD architecture, and
   TARGET_DESC, the current target description, return what
   architecture to use.

   SELECTED may be NULL, in which case we return the architecture
   associated with TARGET_DESC.  If SELECTED specifies a variant
   of the architecture associated with TARGET_DESC, return the
   more specific of the two.

   If SELECTED is a different architecture, but it is accepted as
   compatible by the target, we can use the target architecture.

   If SELECTED is obviously incompatible, warn the user.  */

static const struct bfd_arch_info *
choose_architecture_for_target (const struct target_desc *target_desc,
				const struct bfd_arch_info *selected)
{
  const struct bfd_arch_info *from_target = tdesc_architecture (target_desc);
  const struct bfd_arch_info *compat1, *compat2;

  if (selected == NULL)
    return from_target;

  if (from_target == NULL)
    return selected;

  /* struct bfd_arch_info objects are singletons: that is, there's
     supposed to be exactly one instance for a given machine.  So you
     can tell whether two are equivalent by comparing pointers.  */
  if (from_target == selected)
    return selected;

  /* BFD's 'A->compatible (A, B)' functions return zero if A and B are
     incompatible.  But if they are compatible, it returns the 'more
     featureful' of the two arches.  That is, if A can run code
     written for B, but B can't run code written for A, then it'll
     return A.

     Some targets (e.g. MIPS as of 2006-12-04) don't fully
     implement this, instead always returning NULL or the first
     argument.  We detect that case by checking both directions.  */

  compat1 = selected->compatible (selected, from_target);
  compat2 = from_target->compatible (from_target, selected);

  if (compat1 == NULL && compat2 == NULL)
    {
      /* BFD considers the architectures incompatible.  Check our
	 target description whether it accepts SELECTED as compatible
	 anyway.  */
      if (tdesc_compatible_p (target_desc, selected))
	return from_target;

      warning (_("Selected architecture %s is not compatible "
		 "with reported target architecture %s"),
	       selected->printable_name, from_target->printable_name);
      return selected;
    }

  if (compat1 == NULL)
    return compat2;
  if (compat2 == NULL)
    return compat1;
  if (compat1 == compat2)
    return compat1;

  /* If the two didn't match, but one of them was a default
     architecture, assume the more specific one is correct.  This
     handles the case where an executable or target description just
     says "mips", but the other knows which MIPS variant.  */
  if (compat1->the_default)
    return compat2;
  if (compat2->the_default)
    return compat1;

  /* We have no idea which one is better.  This is a bug, but not
     a critical problem; warn the user.  */
  warning (_("Selected architecture %s is ambiguous with "
	     "reported target architecture %s"),
	   selected->printable_name, from_target->printable_name);
  return selected;
}

/* Functions to manipulate the architecture of the target.  */

enum set_arch { set_arch_auto, set_arch_manual };

static const struct bfd_arch_info *target_architecture_user;

static const char *set_architecture_string;

const char *
selected_architecture_name (void)
{
  if (target_architecture_user == NULL)
    return NULL;
  else
    return set_architecture_string;
}

/* Called if the user enters ``show architecture'' without an
   argument.  */

static void
show_architecture (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  if (target_architecture_user == NULL)
    gdb_printf (file, _("The target architecture is set to "
			"\"auto\" (currently \"%s\").\n"),
		gdbarch_bfd_arch_info (get_current_arch ())->printable_name);
  else
    gdb_printf (file, _("The target architecture is set to \"%s\".\n"),
		set_architecture_string);
}


/* Called if the user enters ``set architecture'' with or without an
   argument.  */

static void
set_architecture (const char *ignore_args,
		  int from_tty, struct cmd_list_element *c)
{
  struct gdbarch_info info;

  if (strcmp (set_architecture_string, "auto") == 0)
    {
      target_architecture_user = NULL;
      if (!gdbarch_update_p (info))
	internal_error (__FILE__, __LINE__,
			_("could not select an architecture automatically"));
    }
  else
    {
      info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
      if (info.bfd_arch_info == NULL)
	internal_error (__FILE__, __LINE__,
			_("set_architecture: bfd_scan_arch failed"));
      if (gdbarch_update_p (info))
	target_architecture_user = info.bfd_arch_info;
      else
	gdb_printf (gdb_stderr,
		    _("Architecture `%s' not recognized.\n"),
		    set_architecture_string);
    }
  show_architecture (gdb_stdout, from_tty, NULL, NULL);
}

/* Try to select a global architecture that matches "info".  Return
   non-zero if the attempt succeeds.  */
int
gdbarch_update_p (struct gdbarch_info info)
{
  struct gdbarch *new_gdbarch;

  /* Check for the current file.  */
  if (info.abfd == NULL)
    info.abfd = current_program_space->exec_bfd ();
  if (info.abfd == NULL)
    info.abfd = core_bfd;

  /* Check for the current target description.  */
  if (info.target_desc == NULL)
    info.target_desc = target_current_description ();

  new_gdbarch = gdbarch_find_by_info (info);

  /* If there no architecture by that name, reject the request.  */
  if (new_gdbarch == NULL)
    {
      if (gdbarch_debug)
	gdb_printf (gdb_stdlog, "gdbarch_update_p: "
		    "Architecture not found\n");
      return 0;
    }

  /* If it is the same old architecture, accept the request (but don't
     swap anything).  */
  if (new_gdbarch == target_gdbarch ())
    {
      if (gdbarch_debug)
	gdb_printf (gdb_stdlog, "gdbarch_update_p: "
		    "Architecture %s (%s) unchanged\n",
		    host_address_to_string (new_gdbarch),
		    gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
      return 1;
    }

  /* It's a new architecture, swap it in.  */
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog, "gdbarch_update_p: "
		"New architecture %s (%s) selected\n",
		host_address_to_string (new_gdbarch),
		gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
  set_target_gdbarch (new_gdbarch);

  return 1;
}

/* Return the architecture for ABFD.  If no suitable architecture
   could be find, return NULL.  */

struct gdbarch *
gdbarch_from_bfd (bfd *abfd)
{
  struct gdbarch_info info;

  info.abfd = abfd;
  return gdbarch_find_by_info (info);
}

/* Set the dynamic target-system-dependent parameters (architecture,
   byte-order) using information found in the BFD */

void
set_gdbarch_from_file (bfd *abfd)
{
  struct gdbarch_info info;
  struct gdbarch *gdbarch;

  info.abfd = abfd;
  info.target_desc = target_current_description ();
  gdbarch = gdbarch_find_by_info (info);

  if (gdbarch == NULL)
    error (_("Architecture of file not recognized."));
  set_target_gdbarch (gdbarch);
}

/* Initialize the current architecture.  Update the ``set
   architecture'' command so that it specifies a list of valid
   architectures.  */

#ifdef DEFAULT_BFD_ARCH
extern const bfd_arch_info_type DEFAULT_BFD_ARCH;
static const bfd_arch_info_type *default_bfd_arch = &DEFAULT_BFD_ARCH;
#else
static const bfd_arch_info_type *default_bfd_arch;
#endif

#ifdef DEFAULT_BFD_VEC
extern const bfd_target DEFAULT_BFD_VEC;
static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC;
#else
static const bfd_target *default_bfd_vec;
#endif

static enum bfd_endian default_byte_order = BFD_ENDIAN_UNKNOWN;

/* Printable names of architectures.  Used as the enum list of the
   "set arch" command.  */
static std::vector<const char *> arches;

void
initialize_current_architecture (void)
{
  arches = gdbarch_printable_names ();
  
  /* Find a default architecture.  */
  if (default_bfd_arch == NULL)
    {
      /* Choose the architecture by taking the first one
	 alphabetically.  */
      const char *chosen = arches[0];

      for (const char *arch : arches)
	{
	  if (strcmp (arch, chosen) < 0)
	    chosen = arch;
	}

      if (chosen == NULL)
	internal_error (__FILE__, __LINE__,
			_("initialize_current_architecture: No arch"));

      default_bfd_arch = bfd_scan_arch (chosen);
      if (default_bfd_arch == NULL)
	internal_error (__FILE__, __LINE__,
			_("initialize_current_architecture: Arch not found"));
    }

  gdbarch_info info;
  info.bfd_arch_info = default_bfd_arch;

  /* Take several guesses at a byte order.  */
  if (default_byte_order == BFD_ENDIAN_UNKNOWN
      && default_bfd_vec != NULL)
    {
      /* Extract BFD's default vector's byte order.  */
      switch (default_bfd_vec->byteorder)
	{
	case BFD_ENDIAN_BIG:
	  default_byte_order = BFD_ENDIAN_BIG;
	  break;
	case BFD_ENDIAN_LITTLE:
	  default_byte_order = BFD_ENDIAN_LITTLE;
	  break;
	default:
	  break;
	}
    }
  if (default_byte_order == BFD_ENDIAN_UNKNOWN)
    {
      /* look for ``*el-*'' in the target name.  */
      const char *chp;
      chp = strchr (target_name, '-');
      if (chp != NULL
	  && chp - 2 >= target_name
	  && startswith (chp - 2, "el"))
	default_byte_order = BFD_ENDIAN_LITTLE;
    }
  if (default_byte_order == BFD_ENDIAN_UNKNOWN)
    {
      /* Wire it to big-endian!!! */
      default_byte_order = BFD_ENDIAN_BIG;
    }

  info.byte_order = default_byte_order;
  info.byte_order_for_code = info.byte_order;

  if (! gdbarch_update_p (info))
    internal_error (__FILE__, __LINE__,
		    _("initialize_current_architecture: Selection of "
		      "initial architecture failed"));

  /* Create the ``set architecture'' command appending ``auto'' to the
     list of architectures.  */
  {
    /* Append ``auto''.  */
    set_architecture_string = "auto";
    arches.push_back (set_architecture_string);
    arches.push_back (nullptr);
    set_show_commands architecture_cmds
      = add_setshow_enum_cmd ("architecture", class_support,
			      arches.data (), &set_architecture_string,
			      _("Set architecture of target."),
			      _("Show architecture of target."), NULL,
			      set_architecture, show_architecture,
			      &setlist, &showlist);
    add_alias_cmd ("processor", architecture_cmds.set, class_support, 1,
		   &setlist);
  }
}

/* Similar to init, but this time fill in the blanks.  Information is
   obtained from the global "set ..." options and explicitly
   initialized INFO fields.  */

void
gdbarch_info_fill (struct gdbarch_info *info)
{
  /* "(gdb) set architecture ...".  */
  if (info->bfd_arch_info == NULL
      && target_architecture_user)
    info->bfd_arch_info = target_architecture_user;
  /* From the file.  */
  if (info->bfd_arch_info == NULL
      && info->abfd != NULL
      && bfd_get_arch (info->abfd) != bfd_arch_unknown
      && bfd_get_arch (info->abfd) != bfd_arch_obscure)
    info->bfd_arch_info = bfd_get_arch_info (info->abfd);
  /* From the target.  */
  if (info->target_desc != NULL)
    info->bfd_arch_info = choose_architecture_for_target
			   (info->target_desc, info->bfd_arch_info);
  /* From the default.  */
  if (info->bfd_arch_info == NULL)
    info->bfd_arch_info = default_bfd_arch;

  /* "(gdb) set byte-order ...".  */
  if (info->byte_order == BFD_ENDIAN_UNKNOWN
      && target_byte_order_user != BFD_ENDIAN_UNKNOWN)
    info->byte_order = target_byte_order_user;
  /* From the INFO struct.  */
  if (info->byte_order == BFD_ENDIAN_UNKNOWN
      && info->abfd != NULL)
    info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG
			: bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
			: BFD_ENDIAN_UNKNOWN);
  /* From the default.  */
  if (info->byte_order == BFD_ENDIAN_UNKNOWN)
    info->byte_order = default_byte_order;
  info->byte_order_for_code = info->byte_order;
  /* Wire the default to the last selected byte order.  */
  default_byte_order = info->byte_order;

  /* "(gdb) set osabi ...".  Handled by gdbarch_lookup_osabi.  */
  /* From the manual override, or from file.  */
  if (info->osabi == GDB_OSABI_UNKNOWN)
    info->osabi = gdbarch_lookup_osabi (info->abfd);
  /* From the target.  */

  if (info->osabi == GDB_OSABI_UNKNOWN && info->target_desc != NULL)
    info->osabi = tdesc_osabi (info->target_desc);
  /* From the configured default.  */
#ifdef GDB_OSABI_DEFAULT
  if (info->osabi == GDB_OSABI_UNKNOWN)
    info->osabi = GDB_OSABI_DEFAULT;
#endif
  /* If we still don't know which osabi to pick, pick none.  */
  if (info->osabi == GDB_OSABI_UNKNOWN)
    info->osabi = GDB_OSABI_NONE;

  /* Must have at least filled in the architecture.  */
  gdb_assert (info->bfd_arch_info != NULL);
}

/* Return "current" architecture.  If the target is running, this is
   the architecture of the selected frame.  Otherwise, the "current"
   architecture defaults to the target architecture.

   This function should normally be called solely by the command
   interpreter routines to determine the architecture to execute a
   command in.  */
struct gdbarch *
get_current_arch (void)
{
  if (has_stack_frames ())
    return get_frame_arch (get_selected_frame (NULL));
  else
    return target_gdbarch ();
}

int
default_has_shared_address_space (struct gdbarch *gdbarch)
{
  /* Simply say no.  In most unix-like targets each inferior/process
     has its own address space.  */
  return 0;
}

int
default_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
				  std::string *msg)
{
  /* We don't know if maybe the target has some way to do fast
     tracepoints that doesn't need gdbarch, so always say yes.  */
  if (msg)
    msg->clear ();
  return 1;
}

const gdb_byte *
default_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
			    int *lenptr)
{
  int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, pcptr);

  return gdbarch_sw_breakpoint_from_kind (gdbarch, kind, lenptr);
}
int
default_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
					    struct regcache *regcache,
					    CORE_ADDR *pcptr)
{
  return gdbarch_breakpoint_kind_from_pc (gdbarch, pcptr);
}


void
default_gen_return_address (struct gdbarch *gdbarch,
			    struct agent_expr *ax, struct axs_value *value,
			    CORE_ADDR scope)
{
  error (_("This architecture has no method to collect a return address."));
}

int
default_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
					struct type *type)
{
  /* Usually, the return value's address is stored the in the "first hidden"
     parameter if the return value should be passed by reference, as
     specified in ABI.  */
  return !(language_pass_by_reference (type).trivially_copyable);
}

int default_insn_is_call (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return 0;
}

int default_insn_is_ret (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return 0;
}

int default_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return 0;
}

/*  See arch-utils.h.  */

bool
default_program_breakpoint_here_p (struct gdbarch *gdbarch,
				   CORE_ADDR address)
{
  int len;
  const gdb_byte *bpoint = gdbarch_breakpoint_from_pc (gdbarch, &address, &len);

  /* Software breakpoints unsupported?  */
  if (bpoint == nullptr)
    return false;

  gdb_byte *target_mem = (gdb_byte *) alloca (len);

  /* Enable the automatic memory restoration from breakpoints while
     we read the memory.  Otherwise we may find temporary breakpoints, ones
     inserted by GDB, and flag them as permanent breakpoints.  */
  scoped_restore restore_memory
    = make_scoped_restore_show_memory_breakpoints (0);

  if (target_read_memory (address, target_mem, len) == 0)
    {
      /* Check if this is a breakpoint instruction for this architecture,
	 including ones used by GDB.  */
      if (memcmp (target_mem, bpoint, len) == 0)
	return true;
    }

  return false;
}

void
default_skip_permanent_breakpoint (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();
  CORE_ADDR current_pc = regcache_read_pc (regcache);
  int bp_len;

  gdbarch_breakpoint_from_pc (gdbarch, &current_pc, &bp_len);
  current_pc += bp_len;
  regcache_write_pc (regcache, current_pc);
}

CORE_ADDR
default_infcall_mmap (CORE_ADDR size, unsigned prot)
{
  error (_("This target does not support inferior memory allocation by mmap."));
}

void
default_infcall_munmap (CORE_ADDR addr, CORE_ADDR size)
{
  /* Memory reserved by inferior mmap is kept leaked.  */
}

/* -mcmodel=large is used so that no GOT (Global Offset Table) is needed to be
   created in inferior memory by GDB (normally it is set by ld.so).  */

std::string
default_gcc_target_options (struct gdbarch *gdbarch)
{
  return string_printf ("-m%d%s", gdbarch_ptr_bit (gdbarch),
			(gdbarch_ptr_bit (gdbarch) == 64
			 ? " -mcmodel=large" : ""));
}

/* gdbarch gnu_triplet_regexp method.  */

const char *
default_gnu_triplet_regexp (struct gdbarch *gdbarch)
{
  return gdbarch_bfd_arch_info (gdbarch)->arch_name;
}

/* Default method for gdbarch_addressable_memory_unit_size.  The default is
   based on the bits_per_byte defined in the bfd library for the current
   architecture, this is usually 8-bits, and so this function will usually
   return 1 indicating 1 byte is 1 octet.  */

int
default_addressable_memory_unit_size (struct gdbarch *gdbarch)
{
  return gdbarch_bfd_arch_info (gdbarch)->bits_per_byte / 8;
}

void
default_guess_tracepoint_registers (struct gdbarch *gdbarch,
				    struct regcache *regcache,
				    CORE_ADDR addr)
{
  int pc_regno = gdbarch_pc_regnum (gdbarch);
  gdb_byte *regs;

  /* This guessing code below only works if the PC register isn't
     a pseudo-register.  The value of a pseudo-register isn't stored
     in the (non-readonly) regcache -- instead it's recomputed
     (probably from some other cached raw register) whenever the
     register is read.  In this case, a custom method implementation
     should be used by the architecture.  */
  if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
    return;

  regs = (gdb_byte *) alloca (register_size (gdbarch, pc_regno));
  store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
			  gdbarch_byte_order (gdbarch), addr);
  regcache->raw_supply (pc_regno, regs);
}

int
default_print_insn (bfd_vma memaddr, disassemble_info *info)
{
  disassembler_ftype disassemble_fn;

  disassemble_fn = disassembler (info->arch, info->endian == BFD_ENDIAN_BIG,
				 info->mach, current_program_space->exec_bfd ());

  gdb_assert (disassemble_fn != NULL);
  return (*disassemble_fn) (memaddr, info);
}

/* See arch-utils.h.  */

CORE_ADDR
gdbarch_skip_prologue_noexcept (gdbarch *gdbarch, CORE_ADDR pc) noexcept
{
  CORE_ADDR new_pc = pc;

  try
    {
      new_pc = gdbarch_skip_prologue (gdbarch, pc);
    }
  catch (const gdb_exception &ex)
    {}

  return new_pc;
}

/* See arch-utils.h.  */

bool
default_in_indirect_branch_thunk (gdbarch *gdbarch, CORE_ADDR pc)
{
  return false;
}

/* See arch-utils.h.  */

ULONGEST
default_type_align (struct gdbarch *gdbarch, struct type *type)
{
  return 0;
}

/* See arch-utils.h.  */

std::string
default_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc)
{
  return "";
}

/* See arch-utils.h.  */
void
default_read_core_file_mappings
  (struct gdbarch *gdbarch,
   struct bfd *cbfd,
   read_core_file_mappings_pre_loop_ftype pre_loop_cb,
   read_core_file_mappings_loop_ftype loop_cb)
{
}

/* Non-zero if we want to trace architecture code.  */

#ifndef GDBARCH_DEBUG
#define GDBARCH_DEBUG 0
#endif
unsigned int gdbarch_debug = GDBARCH_DEBUG;
static void
show_gdbarch_debug (struct ui_file *file, int from_tty,
		    struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Architecture debugging is %s.\n"), value);
}

static const char *
pformat (const struct floatformat **format)
{
  if (format == NULL)
    return "(null)";
  else
    /* Just print out one of them - this is only for diagnostics.  */
    return format[0]->name;
}

static const char *
pstring (const char *string)
{
  if (string == NULL)
    return "(null)";
  return string;
}

static const char *
pstring_ptr (char **string)
{
  if (string == NULL || *string == NULL)
    return "(null)";
  return *string;
}

/* Helper function to print a list of strings, represented as "const
   char *const *".  The list is printed comma-separated.  */

static const char *
pstring_list (const char *const *list)
{
  static char ret[100];
  const char *const *p;
  size_t offset = 0;

  if (list == NULL)
    return "(null)";

  ret[0] = '\0';
  for (p = list; *p != NULL && offset < sizeof (ret); ++p)
    {
      size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p);
      offset += 2 + s;
    }

  if (offset > 0)
    {
      gdb_assert (offset - 2 < sizeof (ret));
      ret[offset - 2] = '\0';
    }

  return ret;
}

#include "gdbarch.c"

obstack *gdbarch_obstack (gdbarch *arch)
{
  return &arch->obstack;
}

/* See gdbarch.h.  */

char *
gdbarch_obstack_strdup (struct gdbarch *arch, const char *string)
{
  return obstack_strdup (&arch->obstack, string);
}


/* Free a gdbarch struct.  This should never happen in normal
   operation --- once you've created a gdbarch, you keep it around.
   However, if an architecture's init function encounters an error
   building the structure, it may need to clean up a partially
   constructed gdbarch.  */

void
gdbarch_free (struct gdbarch *arch)
{
  gdb_assert (arch != NULL);
  gdb_assert (!arch->initialized_p);
  delete arch;
}

/* See gdbarch.h.  */

struct gdbarch_tdep_base *
gdbarch_tdep_1 (struct gdbarch *gdbarch)
{
  if (gdbarch_debug >= 2)
    gdb_printf (gdb_stdlog, "gdbarch_tdep_1 called\n");
  return gdbarch->tdep;
}

registry<gdbarch> *
registry_accessor<gdbarch>::get (gdbarch *arch)
{
  return &arch->registry_fields;
}

/* Keep a registry of the architectures known by GDB.  */

struct gdbarch_registration
{
  enum bfd_architecture bfd_architecture;
  gdbarch_init_ftype *init;
  gdbarch_dump_tdep_ftype *dump_tdep;
  struct gdbarch_list *arches;
  struct gdbarch_registration *next;
};

static struct gdbarch_registration *gdbarch_registry = NULL;

std::vector<const char *>
gdbarch_printable_names ()
{
  /* Accumulate a list of names based on the registed list of
     architectures.  */
  std::vector<const char *> arches;

  for (gdbarch_registration *rego = gdbarch_registry;
       rego != nullptr;
       rego = rego->next)
    {
      const struct bfd_arch_info *ap
	= bfd_lookup_arch (rego->bfd_architecture, 0);
      if (ap == nullptr)
	internal_error (__FILE__, __LINE__,
			_("gdbarch_architecture_names: multi-arch unknown"));
      do
	{
	  arches.push_back (ap->printable_name);
	  ap = ap->next;
	}
      while (ap != NULL);
    }

  return arches;
}


void
gdbarch_register (enum bfd_architecture bfd_architecture,
		  gdbarch_init_ftype *init,
		  gdbarch_dump_tdep_ftype *dump_tdep)
{
  struct gdbarch_registration **curr;
  const struct bfd_arch_info *bfd_arch_info;

  /* Check that BFD recognizes this architecture */
  bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0);
  if (bfd_arch_info == NULL)
    {
      internal_error (__FILE__, __LINE__,
		      _("gdbarch: Attempt to register "
			"unknown architecture (%d)"),
		      bfd_architecture);
    }
  /* Check that we haven't seen this architecture before.  */
  for (curr = &gdbarch_registry;
       (*curr) != NULL;
       curr = &(*curr)->next)
    {
      if (bfd_architecture == (*curr)->bfd_architecture)
	internal_error (__FILE__, __LINE__,
			_("gdbarch: Duplicate registration "
			  "of architecture (%s)"),
			bfd_arch_info->printable_name);
    }
  /* log it */
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog, "gdbarch_register (%s, %s)\n",
		bfd_arch_info->printable_name,
		host_address_to_string (init));
  /* Append it */
  (*curr) = XNEW (struct gdbarch_registration);
  (*curr)->bfd_architecture = bfd_architecture;
  (*curr)->init = init;
  (*curr)->dump_tdep = dump_tdep;
  (*curr)->arches = NULL;
  (*curr)->next = NULL;
}

/* Look for an architecture using gdbarch_info.  */

struct gdbarch_list *
gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
			     const struct gdbarch_info *info)
{
  for (; arches != NULL; arches = arches->next)
    {
      if (info->bfd_arch_info != arches->gdbarch->bfd_arch_info)
	continue;
      if (info->byte_order != arches->gdbarch->byte_order)
	continue;
      if (info->osabi != arches->gdbarch->osabi)
	continue;
      if (info->target_desc != arches->gdbarch->target_desc)
	continue;
      return arches;
    }
  return NULL;
}


/* Find an architecture that matches the specified INFO.  Create a new
   architecture if needed.  Return that new architecture.  */

struct gdbarch *
gdbarch_find_by_info (struct gdbarch_info info)
{
  struct gdbarch *new_gdbarch;
  struct gdbarch_registration *rego;

  /* Fill in missing parts of the INFO struct using a number of
     sources: "set ..."; INFOabfd supplied; and the global
     defaults.  */
  gdbarch_info_fill (&info);

  /* Must have found some sort of architecture.  */
  gdb_assert (info.bfd_arch_info != nullptr);

  if (gdbarch_debug)
    {
      gdb_printf (gdb_stdlog,
		  "gdbarch_find_by_info: info.bfd_arch_info %s\n",
		  (info.bfd_arch_info != nullptr
		   ? info.bfd_arch_info->printable_name
		   : "(null)"));
      gdb_printf (gdb_stdlog,
		  "gdbarch_find_by_info: info.byte_order %d (%s)\n",
		  info.byte_order,
		  (info.byte_order == BFD_ENDIAN_BIG ? "big"
		   : info.byte_order == BFD_ENDIAN_LITTLE ? "little"
		   : "default"));
      gdb_printf (gdb_stdlog,
		  "gdbarch_find_by_info: info.osabi %d (%s)\n",
		  info.osabi, gdbarch_osabi_name (info.osabi));
      gdb_printf (gdb_stdlog,
		  "gdbarch_find_by_info: info.abfd %s\n",
		  host_address_to_string (info.abfd));
    }

  /* Find the tdep code that knows about this architecture.  */
  for (rego = gdbarch_registry;
       rego != nullptr;
       rego = rego->next)
    if (rego->bfd_architecture == info.bfd_arch_info->arch)
      break;
  if (rego == nullptr)
    {
      if (gdbarch_debug)
	gdb_printf (gdb_stdlog, "gdbarch_find_by_info: "
		    "No matching architecture\n");
      return nullptr;
    }

  /* Ask the tdep code for an architecture that matches "info".  */
  new_gdbarch = rego->init (info, rego->arches);

  /* Did the tdep code like it?  No.  Reject the change and revert to
     the old architecture.  */
  if (new_gdbarch == nullptr)
    {
      if (gdbarch_debug)
	gdb_printf (gdb_stdlog, "gdbarch_find_by_info: "
		    "Target rejected architecture\n");
      return nullptr;
    }

  /* Is this a pre-existing architecture (as determined by already
     being initialized)?  Move it to the front of the architecture
     list (keeping the list sorted Most Recently Used).  */
  if (new_gdbarch->initialized_p)
    {
      struct gdbarch_list **list;
      struct gdbarch_list *self;
      if (gdbarch_debug)
	gdb_printf (gdb_stdlog, "gdbarch_find_by_info: "
		    "Previous architecture %s (%s) selected\n",
		    host_address_to_string (new_gdbarch),
		    new_gdbarch->bfd_arch_info->printable_name);
      /* Find the existing arch in the list.  */
      for (list = &rego->arches;
	   (*list) != nullptr && (*list)->gdbarch != new_gdbarch;
	   list = &(*list)->next);
      /* It had better be in the list of architectures.  */
      gdb_assert ((*list) != nullptr && (*list)->gdbarch == new_gdbarch);
      /* Unlink SELF.  */
      self = (*list);
      (*list) = self->next;
      /* Insert SELF at the front.  */
      self->next = rego->arches;
      rego->arches = self;
      /* Return it.  */
      return new_gdbarch;
    }

  /* It's a new architecture.  */
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog, "gdbarch_find_by_info: "
		"New architecture %s (%s) selected\n",
		host_address_to_string (new_gdbarch),
		new_gdbarch->bfd_arch_info->printable_name);

  /* Insert the new architecture into the front of the architecture
     list (keep the list sorted Most Recently Used).  */
  {
    struct gdbarch_list *self = XNEW (struct gdbarch_list);
    self->next = rego->arches;
    self->gdbarch = new_gdbarch;
    rego->arches = self;
  }

  /* Check that the newly installed architecture is valid.  Plug in
     any post init values.  */
  new_gdbarch->dump_tdep = rego->dump_tdep;
  verify_gdbarch (new_gdbarch);
  new_gdbarch->initialized_p = true;

  if (gdbarch_debug)
    gdbarch_dump (new_gdbarch, gdb_stdlog);

  return new_gdbarch;
}

/* Make the specified architecture current.  */

void
set_target_gdbarch (struct gdbarch *new_gdbarch)
{
  gdb_assert (new_gdbarch != NULL);
  gdb_assert (new_gdbarch->initialized_p);
  current_inferior ()->gdbarch = new_gdbarch;
  gdb::observers::architecture_changed.notify (new_gdbarch);
  registers_changed ();
}

/* Return the current inferior's arch.  */

struct gdbarch *
target_gdbarch (void)
{
  return current_inferior ()->gdbarch;
}

void _initialize_gdbarch_utils ();
void
_initialize_gdbarch_utils ()
{
  add_setshow_enum_cmd ("endian", class_support,
			endian_enum, &set_endian_string, 
			_("Set endianness of target."),
			_("Show endianness of target."),
			NULL, set_endian, show_endian,
			&setlist, &showlist);
  add_setshow_zuinteger_cmd ("arch", class_maintenance, &gdbarch_debug, _("\
Set architecture debugging."), _("\
Show architecture debugging."), _("\
When non-zero, architecture debugging is enabled."),
			    NULL,
			    show_gdbarch_debug,
			    &setdebuglist, &showdebuglist);
}
