/* OS ABI variant handling for GDB.

   Copyright (C) 2001-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 "osabi.h"
#include "arch-utils.h"
#include "gdbcmd.h"
#include "command.h"
#include "gdb_bfd.h"

#include "elf-bfd.h"

#ifndef GDB_OSABI_DEFAULT
#define GDB_OSABI_DEFAULT GDB_OSABI_UNKNOWN
#endif

/* State for the "set osabi" command.  */
static enum { osabi_auto, osabi_default, osabi_user } user_osabi_state;
static enum gdb_osabi user_selected_osabi;
static const char *gdb_osabi_available_names[GDB_OSABI_INVALID + 3] = {
  "auto",
  "default",
  "none",
  NULL
};
static const char *set_osabi_string;

/* Names associated with each osabi.  */

struct osabi_names
{
  /* The "pretty" name.  */

  const char *pretty;

  /* The triplet regexp, or NULL if not known.  */

  const char *regexp;
};

/* This table matches the indices assigned to enum gdb_osabi.  Keep
   them in sync.  */
static const struct osabi_names gdb_osabi_names[] =
{
  { "unknown", NULL },
  { "none", NULL },

  { "SVR4", NULL },
  { "GNU/Hurd", NULL },
  { "Solaris", NULL },
  { "GNU/Linux", "linux(-gnu[^-]*)?" },
  { "FreeBSD", NULL },
  { "NetBSD", NULL },
  { "OpenBSD", NULL },
  { "WindowsCE", NULL },
  { "DJGPP", NULL },
  { "QNX-Neutrino", NULL },
  { "Cygwin", NULL },
  { "Windows", NULL },
  { "AIX", NULL },
  { "DICOS", NULL },
  { "Darwin", NULL },
  { "OpenVMS", NULL },
  { "LynxOS178", NULL },
  { "Newlib", NULL },
  { "SDE", NULL },
  { "PikeOS", NULL },

  { "<invalid>", NULL }
};

const char *
gdbarch_osabi_name (enum gdb_osabi osabi)
{
  if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
    return gdb_osabi_names[osabi].pretty;

  return gdb_osabi_names[GDB_OSABI_INVALID].pretty;
}

/* See osabi.h.  */

const char *
osabi_triplet_regexp (enum gdb_osabi osabi)
{
  if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
    return gdb_osabi_names[osabi].regexp;

  return gdb_osabi_names[GDB_OSABI_INVALID].regexp;
}

/* Lookup the OS ABI corresponding to the specified target description
   string.  */

enum gdb_osabi
osabi_from_tdesc_string (const char *name)
{
  int i;

  for (i = 0; i < ARRAY_SIZE (gdb_osabi_names); i++)
    if (strcmp (name, gdb_osabi_names[i].pretty) == 0)
      {
	/* See note above: the name table matches the indices assigned
	   to enum gdb_osabi.  */
	enum gdb_osabi osabi = (enum gdb_osabi) i;

	if (osabi == GDB_OSABI_INVALID)
	  return GDB_OSABI_UNKNOWN;
	else
	  return osabi;
      }

  return GDB_OSABI_UNKNOWN;
}

/* Handler for a given architecture/OS ABI pair.  There should be only
   one handler for a given OS ABI each architecture family.  */
struct gdb_osabi_handler
{
  struct gdb_osabi_handler *next;
  const struct bfd_arch_info *arch_info;
  enum gdb_osabi osabi;
  void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
};

static struct gdb_osabi_handler *gdb_osabi_handler_list;

void
gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
			enum gdb_osabi osabi,
			void (*init_osabi)(struct gdbarch_info,
					   struct gdbarch *))
{
  struct gdb_osabi_handler **handler_p;
  const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine);
  const char **name_ptr;

  /* Registering an OS ABI handler for "unknown" is not allowed.  */
  if (osabi == GDB_OSABI_UNKNOWN)
    {
      internal_error
	(__FILE__, __LINE__,
	 _("gdbarch_register_osabi: An attempt to register a handler for "
	 "OS ABI \"%s\" for architecture %s was made.  The handler will "
	 "not be registered"),
	 gdbarch_osabi_name (osabi),
	 bfd_printable_arch_mach (arch, machine));
      return;
    }

  gdb_assert (arch_info);

  for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
       handler_p = &(*handler_p)->next)
    {
      if ((*handler_p)->arch_info == arch_info
	  && (*handler_p)->osabi == osabi)
	{
	  internal_error
	    (__FILE__, __LINE__,
	     _("gdbarch_register_osabi: A handler for OS ABI \"%s\" "
	     "has already been registered for architecture %s"),
	     gdbarch_osabi_name (osabi),
	     arch_info->printable_name);
	  /* If user wants to continue, override previous definition.  */
	  (*handler_p)->init_osabi = init_osabi;
	  return;
	}
    }

  (*handler_p) = XNEW (struct gdb_osabi_handler);
  (*handler_p)->next = NULL;
  (*handler_p)->arch_info = arch_info;
  (*handler_p)->osabi = osabi;
  (*handler_p)->init_osabi = init_osabi;

  /* Add this OS ABI to the list of enum values for "set osabi", if it isn't
     already there.  */
  for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++)
    {
      if (*name_ptr == gdbarch_osabi_name (osabi))
	return;
    }
  *name_ptr++ = gdbarch_osabi_name (osabi);
  *name_ptr = NULL;
}


/* Sniffer to find the OS ABI for a given file's architecture and flavour.
   It is legal to have multiple sniffers for each arch/flavour pair, to
   disambiguate one OS's a.out from another, for example.  The first sniffer
   to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should
   be careful to claim a file only if it knows for sure what it is.  */
struct gdb_osabi_sniffer
{
  struct gdb_osabi_sniffer *next;
  enum bfd_architecture arch;   /* bfd_arch_unknown == wildcard */
  enum bfd_flavour flavour;
  enum gdb_osabi (*sniffer)(bfd *);
};

static struct gdb_osabi_sniffer *gdb_osabi_sniffer_list;

void
gdbarch_register_osabi_sniffer (enum bfd_architecture arch,
				enum bfd_flavour flavour,
				enum gdb_osabi (*sniffer_fn)(bfd *))
{
  struct gdb_osabi_sniffer *sniffer;

  sniffer = XNEW (struct gdb_osabi_sniffer);
  sniffer->arch = arch;
  sniffer->flavour = flavour;
  sniffer->sniffer = sniffer_fn;

  sniffer->next = gdb_osabi_sniffer_list;
  gdb_osabi_sniffer_list = sniffer;
}


enum gdb_osabi
gdbarch_lookup_osabi (bfd *abfd)
{
  struct gdb_osabi_sniffer *sniffer;
  enum gdb_osabi osabi, match;
  int match_specific;

  /* If we aren't in "auto" mode, return the specified OS ABI.  */
  if (user_osabi_state == osabi_user)
    return user_selected_osabi;

  /* If we don't have a binary, just return unknown.  The caller may
     have other sources the OSABI can be extracted from, e.g., the
     target description.  */
  if (abfd == NULL)
    return GDB_OSABI_UNKNOWN;

  match = GDB_OSABI_UNKNOWN;
  match_specific = 0;

  for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
       sniffer = sniffer->next)
    {
      if ((sniffer->arch == bfd_arch_unknown /* wildcard */
	   || sniffer->arch == bfd_get_arch (abfd))
	  && sniffer->flavour == bfd_get_flavour (abfd))
	{
	  osabi = (*sniffer->sniffer) (abfd);
	  if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
	    {
	      internal_error
		(__FILE__, __LINE__,
		 _("gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
		 "for architecture %s flavour %d"),
		 (int) osabi,
		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
		 (int) bfd_get_flavour (abfd));
	    }
	  else if (osabi != GDB_OSABI_UNKNOWN)
	    {
	      /* A specific sniffer always overrides a generic sniffer.
		 Croak on multiple match if the two matches are of the
		 same class.  If the user wishes to continue, we'll use
		 the first match.  */
	      if (match != GDB_OSABI_UNKNOWN)
		{
		  if ((match_specific && sniffer->arch != bfd_arch_unknown)
		   || (!match_specific && sniffer->arch == bfd_arch_unknown))
		    {
		      internal_error
			(__FILE__, __LINE__,
			 _("gdbarch_lookup_osabi: multiple %sspecific OS ABI "
			 "match for architecture %s flavour %d: first "
			 "match \"%s\", second match \"%s\""),
			 match_specific ? "" : "non-",
			 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
			 (int) bfd_get_flavour (abfd),
			 gdbarch_osabi_name (match),
			 gdbarch_osabi_name (osabi));
		    }
		  else if (sniffer->arch != bfd_arch_unknown)
		    {
		      match = osabi;
		      match_specific = 1;
		    }
		}
	      else
		{
		  match = osabi;
		  if (sniffer->arch != bfd_arch_unknown)
		    match_specific = 1;
		}
	    }
	}
    }

  return match;
}


/* Return non-zero if architecture A can run code written for
   architecture B.  */
static int
can_run_code_for (const struct bfd_arch_info *a, const struct bfd_arch_info *b)
{
  /* 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.

     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.  */
  return (a == b || a->compatible (a, b) == a);
}

/* Return OS ABI handler for INFO.  */

static struct gdb_osabi_handler *
gdbarch_osabi_handler (struct gdbarch_info info)
{
  struct gdb_osabi_handler *handler;

  gdb_assert (info.osabi != GDB_OSABI_UNKNOWN);

  for (handler = gdb_osabi_handler_list; handler != NULL;
       handler = handler->next)
    {
      if (handler->osabi != info.osabi)
	continue;

      /* If the architecture described by ARCH_INFO can run code for
	 the architecture we registered the handler for, then the
	 handler is applicable.  Note, though, that if the handler is
	 for an architecture that is a superset of ARCH_INFO, we can't
	 use that --- it would be perfectly correct for it to install
	 gdbarch methods that refer to registers / instructions /
	 other facilities ARCH_INFO doesn't have.

	 NOTE: kettenis/20021027: There may be more than one machine
	 type that is compatible with the desired machine type.  Right
	 now we simply return the first match, which is fine for now.
	 However, we might want to do something smarter in the future.  */
      /* NOTE: cagney/2003-10-23: The code for "a can_run_code_for b"
	 is implemented using BFD's compatible method (a->compatible
	 (b) == a -- the lowest common denominator between a and b is
	 a).  That method's definition of compatible may not be as you
	 expect.  For instance the test "amd64 can run code for i386"
	 (or more generally "64-bit ISA can run code for the 32-bit
	 ISA").  BFD doesn't normally consider 32-bit and 64-bit
	 "compatible" so it doesn't succeed.  */
      if (can_run_code_for (info.bfd_arch_info, handler->arch_info))
	return handler;
    }

  return nullptr;
}

/* See osabi.h.  */

bool
has_gdb_osabi_handler (struct gdbarch_info info)
{
  return gdbarch_osabi_handler (info) != nullptr;
}

void
gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  struct gdb_osabi_handler *handler;

  gdb_assert (info.osabi != GDB_OSABI_UNKNOWN);
  handler = gdbarch_osabi_handler (info);

  if (handler != nullptr)
    {
      (*handler->init_osabi) (info, gdbarch);
      return;
    }

  if (info.osabi == GDB_OSABI_NONE)
    {
      /* Don't complain about no OSABI.  Assume the user knows
	 what they are doing.  */
      return;
    }

  warning
    ("A handler for the OS ABI \"%s\" is not built into this configuration\n"
     "of GDB.  Attempting to continue with the default %s settings.\n",
     gdbarch_osabi_name (info.osabi),
     info.bfd_arch_info->printable_name);
}

/* Limit on the amount of data to be read.  */
#define MAX_NOTESZ	128

/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  If
   *SECTSIZE is non-zero, then this reads that many bytes from
   the start of the section and clears *SECTSIZE.  */

static int
check_note (bfd *abfd, asection *sect, char *note, unsigned int *sectsize,
	    const char *name, unsigned long descsz, unsigned long type)
{
  unsigned long notesz;

  if (*sectsize)
    {
      if (!bfd_get_section_contents (abfd, sect, note, 0, *sectsize))
	return 0;
      *sectsize = 0;
    }

  /* Calculate the size of this note.  */
  notesz = strlen (name) + 1;
  notesz = ((notesz + 3) & ~3);
  notesz += descsz;
  notesz = ((notesz + 3) & ~3);

  /* If this assertion triggers, increase MAX_NOTESZ.  */
  gdb_assert (notesz <= MAX_NOTESZ);

  /* Check whether SECT is big enough to contain the complete note.  */
  if (notesz > bfd_section_size (sect))
    return 0;

  /* Check the note name.  */
  if (bfd_h_get_32 (abfd, note) != (strlen (name) + 1)
      || strcmp (note + 12, name) != 0)
    return 0;

  /* Check the descriptor size.  */
  if (bfd_h_get_32 (abfd, note + 4) != descsz)
    return 0;

  /* Check the note type.  */
  if (bfd_h_get_32 (abfd, note + 8) != type)
    return 0;

  return 1;
}

/* Generic sniffer for ELF flavoured files.  */

void
generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect,
					  enum gdb_osabi *osabi)
{
  const char *name;
  unsigned int sectsize;
  char *note;

  name = bfd_section_name (sect);
  sectsize = bfd_section_size (sect);

  /* Limit the amount of data to read.  */
  if (sectsize > MAX_NOTESZ)
    sectsize = MAX_NOTESZ;

  /* We lazily read the section data here.  Since we use
     BFD_DECOMPRESS, we can't use bfd_get_section_contents on a
     compressed section.  But, since note sections are not compressed,
     deferring the reading until we recognize the section avoids any
     error.  */
  note = (char *) alloca (sectsize);

  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
  if (strcmp (name, ".note.ABI-tag") == 0)
    {
      /* GNU.  */
      if (check_note (abfd, sect, note, &sectsize, "GNU", 16, NT_GNU_ABI_TAG))
	{
	  unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);

	  switch (abi_tag)
	    {
	    case GNU_ABI_TAG_LINUX:
	      *osabi = GDB_OSABI_LINUX;
	      break;

	    case GNU_ABI_TAG_HURD:
	      *osabi = GDB_OSABI_HURD;
	      break;

	    case GNU_ABI_TAG_SOLARIS:
	      *osabi = GDB_OSABI_SOLARIS;
	      break;

	    case GNU_ABI_TAG_FREEBSD:
	      *osabi = GDB_OSABI_FREEBSD;
	      break;

	    case GNU_ABI_TAG_NETBSD:
	      *osabi = GDB_OSABI_NETBSD;
	      break;

	    default:
	      warning (_("GNU ABI tag value %u unrecognized."), abi_tag);
	      break;
	    }
	  return;
	}

      /* FreeBSD.  */
      if (check_note (abfd, sect, note, &sectsize, "FreeBSD", 4,
		      NT_FREEBSD_ABI_TAG))
	{
	  /* There is no need to check the version yet.  */
	  *osabi = GDB_OSABI_FREEBSD;
	  return;
	}

      return;
    }

  /* .note.netbsd.ident notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsd.ident") == 0
      && check_note (abfd, sect, note, &sectsize, "NetBSD", 4, NT_NETBSD_IDENT))
    {
      /* There is no need to check the version yet.  */
      *osabi = GDB_OSABI_NETBSD;
      return;
    }

  /* .note.openbsd.ident notes, used by OpenBSD.  */
  if (strcmp (name, ".note.openbsd.ident") == 0
      && check_note (abfd, sect, note, &sectsize, "OpenBSD", 4,
		     NT_OPENBSD_IDENT))
    {
      /* There is no need to check the version yet.  */
      *osabi = GDB_OSABI_OPENBSD;
      return;
    }

  /* .note.netbsdcore.procinfo notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsdcore.procinfo") == 0)
    {
      *osabi = GDB_OSABI_NETBSD;
      return;
    }
}

static enum gdb_osabi
generic_elf_osabi_sniffer (bfd *abfd)
{
  unsigned int elfosabi;
  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;

  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];

  switch (elfosabi)
    {
    case ELFOSABI_NONE:
    case ELFOSABI_GNU:
    case ELFOSABI_HPUX:
      /* When the EI_OSABI field in the ELF header is ELFOSABI_NONE
	 (0), then the ELF structures in the file are conforming to
	 the base specification for that machine (there are no
	 OS-specific extensions).  In order to determine the real OS
	 in use, we must look for OS-specific notes.

	 The same applies for ELFOSABI_GNU: this can mean GNU/Hurd,
	 GNU/Linux, and possibly more.  */

      /* And likewise ELFOSABI_HPUX.  For some reason the default
	 value for the EI_OSABI field is ELFOSABI_HPUX for all PA-RISC
	 targets (with the exception of GNU/Linux).  */
      for (asection *sect : gdb_bfd_sections (abfd))
	generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi);
      break;

    case ELFOSABI_FREEBSD:
      osabi = GDB_OSABI_FREEBSD;
      break;

    case ELFOSABI_NETBSD:
      osabi = GDB_OSABI_NETBSD;
      break;

    case ELFOSABI_SOLARIS:
      osabi = GDB_OSABI_SOLARIS;
      break;

    case ELFOSABI_OPENVMS:
      osabi = GDB_OSABI_OPENVMS;
      break;
    }

  if (osabi == GDB_OSABI_UNKNOWN)
    {
      /* The FreeBSD folks have been naughty; they stored the string
	 "FreeBSD" in the padding of the e_ident field of the ELF
	 header to "brand" their ELF binaries in FreeBSD 3.x.  */
      if (memcmp (&elf_elfheader (abfd)->e_ident[8],
		  "FreeBSD", sizeof ("FreeBSD")) == 0)
	osabi = GDB_OSABI_FREEBSD;
    }

  return osabi;
}

static void
set_osabi (const char *args, int from_tty, struct cmd_list_element *c)
{
  if (strcmp (set_osabi_string, "auto") == 0)
    user_osabi_state = osabi_auto;
  else if (strcmp (set_osabi_string, "default") == 0)
    {
      user_selected_osabi = GDB_OSABI_DEFAULT;
      user_osabi_state = osabi_user;
    }
  else
    {
      int i;

      for (i = 1; i < GDB_OSABI_INVALID; i++)
	{
	  enum gdb_osabi osabi = (enum gdb_osabi) i;

	  if (strcmp (set_osabi_string, gdbarch_osabi_name (osabi)) == 0)
	    {
	      user_selected_osabi = osabi;
	      user_osabi_state = osabi_user;
	      break;
	    }
	}
      if (i == GDB_OSABI_INVALID)
	internal_error (__FILE__, __LINE__,
			_("Invalid OS ABI \"%s\" passed to command handler."),
			set_osabi_string);
    }

  /* NOTE: At some point (true multiple architectures) we'll need to be more
     graceful here.  */
  gdbarch_info info;
  if (! gdbarch_update_p (info))
    internal_error (__FILE__, __LINE__, _("Updating OS ABI failed."));
}

static void
show_osabi (struct ui_file *file, int from_tty, struct cmd_list_element *c,
	    const char *value)
{
  if (user_osabi_state == osabi_auto)
    gdb_printf (file,
		_("The current OS ABI is \"auto\" "
		  "(currently \"%s\").\n"),
		gdbarch_osabi_name (gdbarch_osabi (get_current_arch ())));
  else
    gdb_printf (file, _("The current OS ABI is \"%s\".\n"),
		gdbarch_osabi_name (user_selected_osabi));

  if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
    gdb_printf (file, _("The default OS ABI is \"%s\".\n"),
		gdbarch_osabi_name (GDB_OSABI_DEFAULT));
}

void _initialize_gdb_osabi ();
void
_initialize_gdb_osabi ()
{
  if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID].pretty, "<invalid>") != 0)
    internal_error
      (__FILE__, __LINE__,
       _("_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent"));

  /* Register a generic sniffer for ELF flavoured files.  */
  gdbarch_register_osabi_sniffer (bfd_arch_unknown,
				  bfd_target_elf_flavour,
				  generic_elf_osabi_sniffer);

  /* Register the "set osabi" command.  */
  user_osabi_state = osabi_auto;
  set_osabi_string = gdb_osabi_available_names[0];
  gdb_assert (strcmp (set_osabi_string, "auto") == 0);
  add_setshow_enum_cmd ("osabi", class_support, gdb_osabi_available_names,
			&set_osabi_string,
			_("Set OS ABI of target."),
			_("Show OS ABI of target."),
			NULL, set_osabi, show_osabi,
			&setlist, &showlist);
}
