Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH/RFC] Generic OS ABI handling for gdbarch
@ 2002-05-11 21:20 Jason R Thorpe
  2002-05-12 10:06 ` Jason R Thorpe
  2002-05-12 22:20 ` Andrew Cagney
  0 siblings, 2 replies; 9+ messages in thread
From: Jason R Thorpe @ 2002-05-11 21:20 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1258 bytes --]

I started working on generic OS ABI handling for GDB today, lifting from
the various duplicated bits of code in several targets.

There are two pieces to the generic code:

	* OS ABI handlers.  These are basically the same as the OS ABI
	  handlers that exist on a per-target basis, but when they're
	  registered, you now specify a bfd_architecture.  Only one
	  OS ABI can exist per bfd_architecture.

	* OS ABI "sniffers".  These peek at a BFD with a given
	  bfd_architecture/bfd_flavour and determine which OS ABI
	  is correct for that BFD.  Multiple sniffers can exist for
	  a given bfd_architecture/bfd_flavour, e.g. one to sniff out
	  NetBSD a.out, one for FreeBSD a.out, etc.  If a sniffer
	  registers w/ bfd_architecture of "unknown", it can sniff
	  files of any architecture for its flavour.

	  There is a generic ELF sniffer that uses EI_OSABI and note
	  sections.  (This is an example of an arch == "unknown"
	  sniffer.)

	  The first sniffer to return other than GDB_OSABI_UNKNOWN
	  wins, so sniffers should be careful to only claim BFDs
	  they're sure about.

Tomorrow I'll make the Alpha and SH targets use the generic OS ABI
framework as examples.

Comments appreciated.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

[-- Attachment #2: osabi-patch --]
[-- Type: text/plain, Size: 13839 bytes --]

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.184
diff -u -r1.184 Makefile.in
--- Makefile.in	11 May 2002 22:14:19 -0000	1.184
+++ Makefile.in	12 May 2002 04:03:40 -0000
@@ -530,7 +530,7 @@
 	demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
 	event-loop.c event-top.c \
 	expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
-	findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c \
+	findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \
 	inf-loop.c infcmd.c inflow.c infrun.c language.c \
 	kod.c kod-cisco.c \
 	ui-out.c cli-out.c \
@@ -634,6 +634,7 @@
 memattr_h =     memattr.h
 monitor_h =	monitor.h
 objfiles_h =	objfiles.h
+osabi_h =	osabi.h
 parser_defs_h =	parser-defs.h $(doublest_h)
 regcache_h =	regcache.h
 remote_h =	remote.h
@@ -712,7 +713,7 @@
 	symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
 	expprint.o environ.o stack.o thread.o \
 	event-loop.o event-top.o inf-loop.o completer.o \
-	gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
+	gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o $(DEPFILES) \
 	memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
 	builtin-regs.o std-regs.o \
 	signals.o \
@@ -1556,6 +1557,8 @@
 gdbtypes.o: gdbtypes.c $(bfd_h) $(complaints_h) $(defs_h) $(expression_h) \
 	$(gdbtypes_h) $(language_h) $(objfiles_h) $(symfile_h) $(symtab_h) \
 	$(target_h) $(value_h) $(gdb_string_h) $(wrapper_h) $(cp_abi_h)
+
+osabi.o: osabi.c $(defs_h) $(osabi_h) $(BFD_SRC)/elf-bfd.h
 
 go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) gdb_wait.h $(gdbcore_h) \
 	$(command_h) $(floatformat_h) $(target_h) i387-tdep.h $(regcache_h)
Index: osabi.c
===================================================================
RCS file: osabi.c
diff -N osabi.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ osabi.c	12 May 2002 04:03:41 -0000
@@ -0,0 +1,334 @@
+/* OS ABI variant handling for GDB.
+   Copyright 2001, 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "osabi.h"
+#include "elf-bfd.h"
+
+
+/* This table matches the indices assigned to enum gdb_osabi.  Keep
+   them in sync.  */
+static const char * const gdb_osabi_names[] =
+{
+  "<unknown>",
+
+  "SVR4",
+  "GNU Hurd",
+  "Solaris",
+  "OSF/1",
+  "GNU/Linux",
+  "FreeBSD a.out",
+  "FreeBSD ELF",
+  "NetBSD a.out",
+  "NetBSD ELF",
+  "Windows CE",
+
+  "ARM EABI v1"
+  "ARM EABI v2"
+  "ARM APCS",
+
+  NULL
+};
+
+const char *
+gdbarch_osabi_name (enum gdb_osabi osabi)
+{
+  if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
+    return gdb_osabi_names[osabi];
+
+  return "<invalid>";
+}
+
+/* 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;
+  enum bfd_architecture arch;
+  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, enum gdb_osabi osabi,
+                        void (*init_osabi)(struct gdbarch_info,
+					   struct gdbarch *))
+{
+  struct gdb_osabi_handler **handler_p;
+
+  for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
+       handler_p = &(*handler_p)->next)
+    {
+      if ((*handler_p)->arch == arch
+	  && (*handler_p)->osabi == osabi)
+	{
+	  internal_error
+	    (__FILE__, __LINE__,
+	     "gdbarch_register_osabi: A handler for this OS ABI variant "
+	     "(%d) has already been registered for this architecture (%d)",
+	     (int) osabi, (int) arch);
+	  /* If user wants to continue, override previous definition.  */
+	  (*handler_p)->init_osabi = init_osabi;
+	  return;
+	}
+    }
+
+  (*handler_p)
+    = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
+  (*handler_p)->next = NULL;
+  (*handler_p)->arch = arch;
+  (*handler_p)->osabi = osabi;
+  (*handler_p)->init_osabi = init_osabi;
+}
+\f
+
+/* 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 =
+    (struct gdb_osabi_sniffer *) xmalloc (sizeof (struct gdb_osabi_sniffer));
+  sniffer->arch = arch;
+  sniffer->flavour = flavour;
+
+  sniffer->next = gdb_osabi_sniffer_list;
+  gdb_osabi_sniffer_list = sniffer;
+}
+\f
+
+enum gdb_osabi
+gdbarch_lookup_osabi (bfd *abfd)
+{
+  struct gdb_osabi_sniffer *sniffer;
+  enum gdb_osabi osabi;
+
+  for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
+       sniffer = sniffer->next)
+    {
+      if ((sniffer->arch == bfd_arch_unknown /* wildcard */
+	   || sniffer->arch == abfd->arch_info->arch)
+	  && sniffer->flavour == abfd->xvec->flavour)
+	{
+	  osabi = (*sniffer->sniffer) (abfd);
+	  if (osabi != GDB_OSABI_UNKNOWN)
+	    return osabi;
+	}
+    }
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+int
+gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch,
+                    enum gdb_osabi osabi)
+{
+  struct gdb_osabi_handler *handler;
+  bfd *abfd = info.abfd;
+
+  for (handler = gdb_osabi_handler_list; handler != NULL;
+       handler = handler->next)
+    {
+      if (handler->arch == abfd->arch_info->arch
+	  && handler->osabi == osabi)
+	{
+	  (*handler->init_osabi) (info, gdbarch);
+	  return 0;
+	}
+    }
+
+  /* Let the caller decide how much to complain.  */
+  return 1;
+}
+\f
+
+/* Generic sniffer for ELF flavoured files.  */
+
+static void
+process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+  enum gdb_osabi *os_ident_ptr = obj;
+  const char *name;
+  unsigned int sectsize;
+
+  name = bfd_get_section_name (abfd, sect);
+  sectsize = bfd_section_size (abfd, sect);
+
+  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
+  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+    {
+      unsigned int name_length, data_length, note_type;
+      char *note;
+
+      /* If the section is larger than this, it's probably not what we are
+	 looking for.  */
+      if (sectsize > 128)
+	sectsize = 128;
+
+      note = alloca (sectsize);
+
+      bfd_get_section_contents (abfd, sect, note,
+				(file_ptr) 0, (bfd_size_type) sectsize);
+
+      name_length = bfd_h_get_32 (abfd, note);
+      data_length = bfd_h_get_32 (abfd, note + 4);
+      note_type   = bfd_h_get_32 (abfd, note + 8);
+
+      if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
+	  && strcmp (note + 12, "GNU") == 0)
+	{
+	  int os_number = bfd_h_get_32 (abfd, note + 16);
+
+	  switch (os_number)
+	    {
+	    case GNU_ABI_TAG_LINUX:
+	      *os_ident_ptr = GDB_OSABI_LINUX;
+	      break;
+
+	    case GNU_ABI_TAG_HURD:
+	      *os_ident_ptr = GDB_OSABI_HURD;
+	      break;
+
+	    case GNU_ABI_TAG_SOLARIS:
+	      *os_ident_ptr = GDB_OSABI_SOLARIS;
+	      break;
+
+	    default:
+	      internal_error
+		(__FILE__, __LINE__,
+		 "process_note_abi_sections: unknown OS number %d",
+		 os_number);
+	    }
+	  return;
+	}
+      else if (name_length == 8 && data_length == 4
+	       && note_type == NT_FREEBSD_ABI_TAG
+	       && strcmp (note + 12, "FreeBSD") == 0)
+	{
+	  /* XXX Should we check the version here?  Probably not
+	     necessary yet.  */
+	  *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
+	}
+      return;
+    }
+
+  /* .note.netbsd.ident notes, used by NetBSD.  */
+  if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
+    {
+      unsigned int name_length, data_length, note_type;
+      char *note;
+
+      /* If the section is larger than this, it's probably not what we are
+	 looking for.  */
+      if (sectsize > 128) 
+	sectsize = 128;
+
+      note = alloca (sectsize);
+
+      bfd_get_section_contents (abfd, sect, note,
+				(file_ptr) 0, (bfd_size_type) sectsize);
+      
+      name_length = bfd_h_get_32 (abfd, note);
+      data_length = bfd_h_get_32 (abfd, note + 4);
+      note_type   = bfd_h_get_32 (abfd, note + 8);
+
+      if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
+	  && strcmp (note + 12, "NetBSD") == 0)
+	{
+	  /* XXX Should we check the version here?  Probably not
+	     necessary yet.  */
+	  *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
+	}
+      return;
+    }
+}
+
+static enum gdb_osabi
+generic_elf_osabi_sniffer (bfd *abfd)
+{
+  int elfosabi;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+  switch (elfosabi)
+    {
+    case ELFOSABI_NONE:
+      /* When elfosabi is ELFOSABI_NONE (0), this is supposed to indicate
+	 that we're on a SVR4 system.  However, some systems use note sections
+	 to record OS/ABI info, but leave e_ident[EI_OSABI] zero.  So we
+	 have to check the note sections, too.  */
+      bfd_map_over_sections (abfd,
+			     process_note_abi_tag_sections,
+			     &osabi);
+      break;
+
+    case ELFOSABI_FREEBSD:
+      osabi = GDB_OSABI_FREEBSD_ELF;
+      break;
+
+    case ELFOSABI_NETBSD:
+      osabi = GDB_OSABI_NETBSD_ELF;
+      break;
+
+    case ELFOSABI_LINUX:
+      osabi = GDB_OSABI_LINUX;
+      break;
+
+    case ELFOSABI_HURD:
+      osabi = GDB_OSABI_HURD;
+      break;
+
+    case ELFOSABI_SOLARIS:
+      osabi = GDB_OSABI_SOLARIS;
+      break;
+    }
+
+  return osabi;
+}
+\f
+
+void
+_initialize_gdb_osabi (void)
+{
+  /* Register a generic sniffer for ELF flavoured files.  */
+  gdbarch_register_osabi_sniffer (bfd_arch_unknown,
+				  bfd_target_elf_flavour,
+				  generic_elf_osabi_sniffer);
+}
Index: osabi.h
===================================================================
RCS file: osabi.h
diff -N osabi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ osabi.h	12 May 2002 04:03:41 -0000
@@ -0,0 +1,72 @@
+/* OS ABI variant handling for GDB.
+   Copyright 2001, 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef OSABI_H
+#define OSABI_H
+
+/* List of known OS ABIs.  If you change this, make sure to update the
+   table in osabi.c.  */
+enum gdb_osabi
+{
+  GDB_OSABI_UNKNOWN = 0,	/* keep this first */
+
+  GDB_OSABI_SVR4,
+  GDB_OSABI_HURD,
+  GDB_OSABI_SOLARIS,
+  GDB_OSABI_OSF1,
+  GDB_OSABI_LINUX,
+  GDB_OSABI_FREEBSD_AOUT,
+  GDB_OSABI_FREEBSD_ELF,
+  GDB_OSABI_NETBSD_AOUT,
+  GDB_OSABI_NETBSD_ELF,
+  GDB_OSABI_WINCE,
+
+  GDB_OSABI_ARM_EABI_V1,
+  GDB_OSABI_ARM_EABI_V2,
+  GDB_OSABI_ARM_APCS,
+
+  GDB_OSABI_INVALID		/* keep this last */
+};
+
+/* Register an OS ABI sniffer.  Each arch/flavour may have more than
+   one sniffer.  This is used to e.g. differentiate one OS's a.out from
+   another.  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.  */
+void gdbarch_register_osabi_sniffer (enum bfd_architecture,
+				     enum bfd_flavour,
+				     enum gdb_osabi (*)(bfd *));
+
+/* Register a handler for an OS ABI variant for a given architecture.  There
+   should be only one handler for a given OS ABI each architecture family.  */
+void gdbarch_register_osabi (enum bfd_architecture, enum gdb_osabi,
+                             void (*)(struct gdbarch_info,
+				      struct gdbarch *));
+
+/* Lookup the OS ABI corresponding to the specified BFD.  */
+enum gdb_osabi gdbarch_lookup_osabi (bfd *);
+
+/* Initialize the gdbarch for the specified OS ABI variant.  */
+int gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *, enum gdb_osabi);
+
+/* Return the name of the specified OS ABI.  */
+const char *gdbarch_osabi_name (enum gdb_osabi);
+
+#endif /* OSABI_H */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-11 21:20 [PATCH/RFC] Generic OS ABI handling for gdbarch Jason R Thorpe
@ 2002-05-12 10:06 ` Jason R Thorpe
  2002-05-12 21:50   ` Eli Zaretskii
  2002-05-12 22:20 ` Andrew Cagney
  1 sibling, 1 reply; 9+ messages in thread
From: Jason R Thorpe @ 2002-05-12 10:06 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 438 bytes --]

On Sat, May 11, 2002 at 09:20:46PM -0700, Jason R Thorpe wrote:

 > Tomorrow I'll make the Alpha and SH targets use the generic OS ABI
 > framework as examples.

Ok, as promised.  I also cleaned up some of the bfd usage in osabi.c,
and pushed some more work into gdbarch_init_osabi().

Built with alpha-netbsd, sh-netbsdelf, and sh-elf targets.

Again, comments appreciated :-)

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

[-- Attachment #2: osabi-patch --]
[-- Type: text/plain, Size: 47344 bytes --]

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.184
diff -u -r1.184 Makefile.in
--- Makefile.in	11 May 2002 22:14:19 -0000	1.184
+++ Makefile.in	12 May 2002 16:42:59 -0000
@@ -530,7 +530,7 @@
 	demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
 	event-loop.c event-top.c \
 	expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
-	findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c \
+	findvar.c regcache.c gdbarch.c arch-utils.c gdbtypes.c osabi.c \
 	inf-loop.c infcmd.c inflow.c infrun.c language.c \
 	kod.c kod-cisco.c \
 	ui-out.c cli-out.c \
@@ -634,6 +634,7 @@
 memattr_h =     memattr.h
 monitor_h =	monitor.h
 objfiles_h =	objfiles.h
+osabi_h =	osabi.h
 parser_defs_h =	parser-defs.h $(doublest_h)
 regcache_h =	regcache.h
 remote_h =	remote.h
@@ -712,7 +713,7 @@
 	symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
 	expprint.o environ.o stack.o thread.o \
 	event-loop.o event-top.o inf-loop.o completer.o \
-	gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
+	gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o $(DEPFILES) \
 	memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
 	builtin-regs.o std-regs.o \
 	signals.o \
@@ -1556,6 +1557,8 @@
 gdbtypes.o: gdbtypes.c $(bfd_h) $(complaints_h) $(defs_h) $(expression_h) \
 	$(gdbtypes_h) $(language_h) $(objfiles_h) $(symfile_h) $(symtab_h) \
 	$(target_h) $(value_h) $(gdb_string_h) $(wrapper_h) $(cp_abi_h)
+
+osabi.o: osabi.c $(defs_h) $(osabi_h) $(BFD_SRC)/elf-bfd.h
 
 go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) gdb_wait.h $(gdbcore_h) \
 	$(command_h) $(floatformat_h) $(target_h) i387-tdep.h $(regcache_h)
Index: alpha-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-linux-tdep.c,v
retrieving revision 1.5
diff -u -r1.5 alpha-linux-tdep.c
--- alpha-linux-tdep.c	26 Apr 2002 07:05:34 -0000	1.5
+++ alpha-linux-tdep.c	12 May 2002 16:42:59 -0000
@@ -116,5 +116,6 @@
 void
 _initialize_alpha_linux_tdep (void)
 {
-  alpha_gdbarch_register_os_abi (ALPHA_ABI_LINUX, alpha_linux_init_abi);
+  gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_LINUX,
+                          alpha_linux_init_abi);
 }
Index: alpha-osf1-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-osf1-tdep.c,v
retrieving revision 1.4
diff -u -r1.4 alpha-osf1-tdep.c
--- alpha-osf1-tdep.c	26 Apr 2002 07:05:34 -0000	1.4
+++ alpha-osf1-tdep.c	12 May 2002 16:42:59 -0000
@@ -69,5 +69,5 @@
 void
 _initialize_alpha_osf1_tdep (void)
 {
-  alpha_gdbarch_register_os_abi (ALPHA_ABI_OSF1, alpha_osf1_init_abi);
+  gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_OSF1, alpha_osf1_init_abi);
 }
Index: alpha-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
retrieving revision 1.33
diff -u -r1.33 alpha-tdep.c
--- alpha-tdep.c	5 May 2002 18:49:57 -0000	1.33
+++ alpha-tdep.c	12 May 2002 16:43:01 -0000
@@ -1766,186 +1766,6 @@
 }
 
 \f
-/* This table matches the indices assigned to enum alpha_abi.  Keep
-   them in sync.  */
-static const char * const alpha_abi_names[] =
-{
-  "<unknown>",
-  "OSF/1",
-  "GNU/Linux",
-  "FreeBSD",
-  "NetBSD",
-  NULL
-};
-
-static void
-process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
-{
-  enum alpha_abi *os_ident_ptr = obj;
-  const char *name;
-  unsigned int sectsize;
-
-  name = bfd_get_section_name (abfd, sect);
-  sectsize = bfd_section_size (abfd, sect);
-
-  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, data_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we are
-	 looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
-
-      name_length = bfd_h_get_32 (abfd, note);
-      data_length = bfd_h_get_32 (abfd, note + 4);
-      note_type   = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 4 && data_length == 16 && note_type == 1
-	  && strcmp (note + 12, "GNU") == 0)
-	{
-	  int os_number = bfd_h_get_32 (abfd, note + 16);
-
-	  /* The case numbers are from abi-tags in glibc.  */
-	  switch (os_number)
-	    {
-	    case 0 :
-	      *os_ident_ptr = ALPHA_ABI_LINUX;
-	      break;
-
-	    case 1 :
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: Hurd objects not supported");
-	      break;
-
-	    case 2 :
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: Solaris objects not supported");
-	      break;
-
-	    default :
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: unknown OS number %d",
-		 os_number);
-	      break;
-	    }
-	}
-    }
-  /* NetBSD uses a similar trick.  */
-  else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, desc_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we are
-         looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				 (file_ptr) 0, (bfd_size_type) sectsize);
-      
-      name_length = bfd_h_get_32 (abfd, note);
-      desc_length = bfd_h_get_32 (abfd, note + 4);
-      note_type   = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 7 && desc_length == 4 && note_type == 1
-	  && strcmp (note + 12, "NetBSD") == 0)
-	/* XXX Should we check the version here?
-	   Probably not necessary yet.  */
-	*os_ident_ptr = ALPHA_ABI_NETBSD;
-    }
-}
-
-static int
-get_elfosabi (bfd *abfd)
-{
-  int elfosabi;
-  enum alpha_abi alpha_abi = ALPHA_ABI_UNKNOWN;
-
-  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
-
-  /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
-     what we're on a SYSV system.  However, GNU/Linux uses a note section
-     to record OS/ABI info, but leaves e_ident[EI_OSABI] zero.  So we
-     have to check the note sections too.  */
-  if (elfosabi == 0)
-    {
-      bfd_map_over_sections (abfd,
-			     process_note_abi_tag_sections,
-			     &alpha_abi);
-    }
-
-  if (alpha_abi != ALPHA_ABI_UNKNOWN)
-    return alpha_abi;
-
-  switch (elfosabi)
-    {
-    case ELFOSABI_NONE:
-      /* Leave it as unknown.  */
-      break;
-
-    case ELFOSABI_NETBSD:
-      return ALPHA_ABI_NETBSD;
-
-    case ELFOSABI_FREEBSD:
-      return ALPHA_ABI_FREEBSD;
-
-    case ELFOSABI_LINUX:
-      return ALPHA_ABI_LINUX;
-    }
-
-  return ALPHA_ABI_UNKNOWN;
-}
-
-struct alpha_abi_handler
-{
-  struct alpha_abi_handler *next;
-  enum alpha_abi abi;
-  void (*init_abi)(struct gdbarch_info, struct gdbarch *);
-};
-
-struct alpha_abi_handler *alpha_abi_handler_list = NULL;
-
-void
-alpha_gdbarch_register_os_abi (enum alpha_abi abi,
-                               void (*init_abi)(struct gdbarch_info,
-						struct gdbarch *))
-{
-  struct alpha_abi_handler **handler_p;
-
-  for (handler_p = &alpha_abi_handler_list; *handler_p != NULL;
-       handler_p = &(*handler_p)->next)
-    {
-      if ((*handler_p)->abi == abi)
-	{
-	  internal_error
-	    (__FILE__, __LINE__,
-	     "alpha_gdbarch_register_os_abi: A handler for this ABI variant "
-	     "(%d) has already been registered", (int) abi);
-	  /* If user wants to continue, override previous definition.  */
-	  (*handler_p)->init_abi = init_abi;
-	  return;
-	}
-    }
-
-  (*handler_p)
-    = (struct alpha_abi_handler *) xmalloc (sizeof (struct alpha_abi_handler));
-  (*handler_p)->next = NULL;
-  (*handler_p)->abi = abi;
-  (*handler_p)->init_abi = init_abi;
-}
 
 /* Initialize the current architecture based on INFO.  If possible, re-use an
    architecture from ARCHES, which is a list of architectures already created
@@ -1959,27 +1779,18 @@
 {
   struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
-  enum alpha_abi alpha_abi = ALPHA_ABI_UNKNOWN;
-  struct alpha_abi_handler *abi_handler;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
   /* Try to determine the ABI of the object we are loading.  */
 
   if (info.abfd != NULL)
     {
-      switch (bfd_get_flavour (info.abfd))
+      osabi = gdbarch_lookup_osabi (info.abfd);
+      if (osabi == GDB_OSABI_UNKNOWN)
 	{
-	case bfd_target_elf_flavour:
-	  alpha_abi = get_elfosabi (info.abfd);
-	  break;
-
-	case bfd_target_ecoff_flavour:
-	  /* Assume it's OSF/1.  */
-	  alpha_abi = ALPHA_ABI_OSF1;
-          break;
-
-	default:
-	  /* Not sure what to do here, leave the ABI as unknown.  */
-	  break;
+	  /* If it's an ECOFF file, assume it's OSF/1.  */
+	  if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour)
+	    osabi = GDB_OSABI_OSF1;
 	}
     }
 
@@ -1990,22 +1801,14 @@
     {
       /* Make sure the ABI selection matches.  */
       tdep = gdbarch_tdep (arches->gdbarch);
-      if (tdep && tdep->alpha_abi == alpha_abi)
+      if (tdep && tdep->osabi == osabi)
 	return arches->gdbarch;
     }
 
   tdep = xmalloc (sizeof (struct gdbarch_tdep));
   gdbarch = gdbarch_alloc (&info, tdep);
 
-  tdep->alpha_abi = alpha_abi;
-  if (alpha_abi < ALPHA_ABI_INVALID)
-    tdep->abi_name = alpha_abi_names[alpha_abi];
-  else
-    {
-      internal_error (__FILE__, __LINE__, "Invalid setting of alpha_abi %d",
-		      (int) alpha_abi);
-      tdep->abi_name = "<invalid>";
-    }
+  tdep->osabi = osabi;
 
   /* Lowest text address.  This is used by heuristic_proc_start() to
      decide when to stop looking.  */
@@ -2122,38 +1925,7 @@
   set_gdbarch_frame_args_skip (gdbarch, 0);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
-  if (alpha_abi == ALPHA_ABI_UNKNOWN)
-    {
-      /* Don't complain about not knowing the ABI variant if we don't
-	 have an inferior.  */
-      if (info.abfd)
-	fprintf_filtered
-	  (gdb_stderr, "GDB doesn't recognize the ABI of the inferior.  "
-	   "Attempting to continue with the default Alpha settings");
-    }
-  else
-    {
-      for (abi_handler = alpha_abi_handler_list; abi_handler != NULL;
-	   abi_handler = abi_handler->next)
-	if (abi_handler->abi == alpha_abi)
-	  break;
-
-      if (abi_handler)
-	abi_handler->init_abi (info, gdbarch);
-      else
-	{
-	  /* We assume that if GDB_MULTI_ARCH is less than
-	     GDB_MULTI_ARCH_TM that an ABI variant can be supported by
-	     overriding definitions in this file.  */
-	  if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-	    fprintf_filtered
-	      (gdb_stderr,
-	       "A handler for the ABI variant \"%s\" is not built into this "
-	       "configuration of GDB.  "
-	       "Attempting to continue with the default Alpha settings",
-	       alpha_abi_names[alpha_abi]);
-	}
-    }
+  gdbarch_init_osabi (info, gdbarch, osabi);
 
   /* Now that we have tuned the configuration, set a few final things
      based on what the OS ABI has told us.  */
@@ -2172,12 +1944,8 @@
   if (tdep == NULL)
     return;
 
-  if (tdep->abi_name != NULL)
-    fprintf_unfiltered (file, "alpha_dump_tdep: ABI = %s\n", tdep->abi_name);
-  else
-    internal_error (__FILE__, __LINE__,
-		    "alpha_dump_tdep: illegal setting of tdep->alpha_abi (%d)",
-		    (int) tdep->alpha_abi);
+  fprintf_unfiltered (file, "alpha_dump_tdep: OS ABI = %s\n",
+		      gdbarch_osabi_name (tdep->osabi));
 
   fprintf_unfiltered (file,
                       "alpha_dump_tdep: vm_min_address = 0x%lx\n",
Index: alpha-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.h,v
retrieving revision 1.7
diff -u -r1.7 alpha-tdep.h
--- alpha-tdep.h	26 Apr 2002 07:05:34 -0000	1.7
+++ alpha-tdep.h	12 May 2002 16:43:01 -0000
@@ -22,6 +22,8 @@
 #ifndef ALPHA_TDEP_H
 #define ALPHA_TDEP_H
 
+#include "osabi.h"
+
 /* Say how long (ordinary) registers are.  This is a piece of bogosity
    used in push_word and a few other places;  REGISTER_RAW_SIZE is the
    real way to know how big a register is.  */
@@ -76,24 +78,10 @@
    pointer, the value of localoff is obtained from the PDR.  */
 #define ALPHA_NUM_ARG_REGS   6
 
-/* ABI variants that we know about.  If you add to this enum, please
-   update the table of names in alpha-tdep.c.  */
-enum alpha_abi
-{
-  ALPHA_ABI_UNKNOWN = 0,
-  ALPHA_ABI_OSF1,
-  ALPHA_ABI_LINUX,
-  ALPHA_ABI_FREEBSD,
-  ALPHA_ABI_NETBSD,
-
-  ALPHA_ABI_INVALID	/* Keep this last. */
-};
-
 /* Target-dependent structure in gdbarch.  */
 struct gdbarch_tdep
 {
-  enum alpha_abi alpha_abi;	/* OS/ABI of inferior.  */
-  const char *abi_name;		/* Name of the above.  */
+  enum gdb_osabi osabi;		/* OS/ABI of inferior.  */
 
   CORE_ADDR vm_min_address;	/* used by heuristic_proc_start */
 
@@ -117,9 +105,5 @@
 };
 
 void alpha_software_single_step (enum target_signal, int);
-
-void alpha_gdbarch_register_os_abi (enum alpha_abi,
-                                    void (*init_abi)(struct gdbarch_info,
-						     struct gdbarch *));
 
 #endif /* ALPHA_TDEP_H */
Index: alphafbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alphafbsd-tdep.c,v
retrieving revision 1.4
diff -u -r1.4 alphafbsd-tdep.c
--- alphafbsd-tdep.c	26 Apr 2002 01:08:19 -0000	1.4
+++ alphafbsd-tdep.c	12 May 2002 16:43:01 -0000
@@ -78,5 +78,6 @@
 void
 _initialize_alphafbsd_tdep (void)
 {
-  alpha_gdbarch_register_os_abi (ALPHA_ABI_FREEBSD, alphafbsd_init_abi);
+  gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_FREEBSD_ELF,
+                          alphafbsd_init_abi);
 }
Index: alphanbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alphanbsd-tdep.c,v
retrieving revision 1.5
diff -u -r1.5 alphanbsd-tdep.c
--- alphanbsd-tdep.c	11 May 2002 22:14:19 -0000	1.5
+++ alphanbsd-tdep.c	12 May 2002 16:43:01 -0000
@@ -203,7 +203,8 @@
 void
 _initialize_alphanbsd_tdep (void)
 {
-  alpha_gdbarch_register_os_abi (ALPHA_ABI_NETBSD, alphanbsd_init_abi);
+  gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_NETBSD_ELF,
+                          alphanbsd_init_abi);
 
   add_core_fns (&alphanbsd_core_fns);
   add_core_fns (&alphanbsd_elfcore_fns);
Index: osabi.c
===================================================================
RCS file: osabi.c
diff -N osabi.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ osabi.c	12 May 2002 16:43:02 -0000
@@ -0,0 +1,371 @@
+/* OS ABI variant handling for GDB.
+   Copyright 2001, 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "osabi.h"
+#include "elf-bfd.h"
+
+
+/* This table matches the indices assigned to enum gdb_osabi.  Keep
+   them in sync.  */
+static const char * const gdb_osabi_names[] =
+{
+  "<unknown>",
+
+  "SVR4",
+  "GNU Hurd",
+  "Solaris",
+  "OSF/1",
+  "GNU/Linux",
+  "FreeBSD a.out",
+  "FreeBSD ELF",
+  "NetBSD a.out",
+  "NetBSD ELF",
+  "Windows CE",
+
+  "ARM EABI v1"
+  "ARM EABI v2"
+  "ARM APCS",
+
+  NULL
+};
+
+const char *
+gdbarch_osabi_name (enum gdb_osabi osabi)
+{
+  if (osabi >= GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
+    return gdb_osabi_names[osabi];
+
+  return "<invalid>";
+}
+
+/* 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;
+  enum bfd_architecture arch;
+  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, enum gdb_osabi osabi,
+                        void (*init_osabi)(struct gdbarch_info,
+					   struct gdbarch *))
+{
+  struct gdb_osabi_handler **handler_p;
+
+  /* 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, 0));
+      return;
+    }
+
+  for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
+       handler_p = &(*handler_p)->next)
+    {
+      if ((*handler_p)->arch == arch
+	  && (*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),
+	     bfd_printable_arch_mach (arch, 0));
+	  /* If user wants to continue, override previous definition.  */
+	  (*handler_p)->init_osabi = init_osabi;
+	  return;
+	}
+    }
+
+  (*handler_p)
+    = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
+  (*handler_p)->next = NULL;
+  (*handler_p)->arch = arch;
+  (*handler_p)->osabi = osabi;
+  (*handler_p)->init_osabi = init_osabi;
+}
+\f
+
+/* 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 =
+    (struct gdb_osabi_sniffer *) xmalloc (sizeof (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;
+}
+\f
+
+enum gdb_osabi
+gdbarch_lookup_osabi (bfd *abfd)
+{
+  struct gdb_osabi_sniffer *sniffer;
+  enum gdb_osabi osabi;
+
+  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)
+	    return osabi;
+	}
+    }
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+void
+gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch,
+                    enum gdb_osabi osabi)
+{
+  struct gdb_osabi_handler *handler;
+  bfd *abfd = info.abfd;
+  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
+
+  if (osabi == GDB_OSABI_UNKNOWN)
+    {
+      /* Don't complain about not knowing the OS ABI if we don't
+	 have an inferior.  */
+      if (info.abfd)
+	fprintf_filtered
+	  (gdb_stderr, "GDB doesn't recognize the OS ABI of the inferior.  "
+	   "Attempting to continue with the default %s settings",
+	   bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
+      return;
+    }
+
+  for (handler = gdb_osabi_handler_list; handler != NULL;
+       handler = handler->next)
+    {
+      if (handler->arch == bfd_get_arch (abfd)
+	  && handler->osabi == osabi)
+	{
+	  (*handler->init_osabi) (info, gdbarch);
+	  return;
+	}
+    }
+
+  /* We assume that if GDB_MULTI_ARCH is less than
+     GDB_MULTI_ARCH_TM that an ABI variant can be supported by
+     overriding definitions in the tm-file.  */
+  if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
+    fprintf_filtered
+      (gdb_stderr,
+       "A handler for the OS ABI \"%s\" is not built into this "
+       "configuration of GDB.  "
+       "Attempting to continue with the default %s settings",
+       gdbarch_osabi_name (osabi),
+       bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
+}
+\f
+
+/* Generic sniffer for ELF flavoured files.  */
+
+static void
+process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+  enum gdb_osabi *os_ident_ptr = obj;
+  const char *name;
+  unsigned int sectsize;
+
+  name = bfd_get_section_name (abfd, sect);
+  sectsize = bfd_section_size (abfd, sect);
+
+  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
+  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
+    {
+      unsigned int name_length, data_length, note_type;
+      char *note;
+
+      /* If the section is larger than this, it's probably not what we are
+	 looking for.  */
+      if (sectsize > 128)
+	sectsize = 128;
+
+      note = alloca (sectsize);
+
+      bfd_get_section_contents (abfd, sect, note,
+				(file_ptr) 0, (bfd_size_type) sectsize);
+
+      name_length = bfd_h_get_32 (abfd, note);
+      data_length = bfd_h_get_32 (abfd, note + 4);
+      note_type   = bfd_h_get_32 (abfd, note + 8);
+
+      if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
+	  && strcmp (note + 12, "GNU") == 0)
+	{
+	  int os_number = bfd_h_get_32 (abfd, note + 16);
+
+	  switch (os_number)
+	    {
+	    case GNU_ABI_TAG_LINUX:
+	      *os_ident_ptr = GDB_OSABI_LINUX;
+	      break;
+
+	    case GNU_ABI_TAG_HURD:
+	      *os_ident_ptr = GDB_OSABI_HURD;
+	      break;
+
+	    case GNU_ABI_TAG_SOLARIS:
+	      *os_ident_ptr = GDB_OSABI_SOLARIS;
+	      break;
+
+	    default:
+	      internal_error
+		(__FILE__, __LINE__,
+		 "process_note_abi_sections: unknown OS number %d",
+		 os_number);
+	    }
+	  return;
+	}
+      else if (name_length == 8 && data_length == 4
+	       && note_type == NT_FREEBSD_ABI_TAG
+	       && strcmp (note + 12, "FreeBSD") == 0)
+	{
+	  /* XXX Should we check the version here?  Probably not
+	     necessary yet.  */
+	  *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
+	}
+      return;
+    }
+
+  /* .note.netbsd.ident notes, used by NetBSD.  */
+  if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
+    {
+      unsigned int name_length, data_length, note_type;
+      char *note;
+
+      /* If the section is larger than this, it's probably not what we are
+	 looking for.  */
+      if (sectsize > 128) 
+	sectsize = 128;
+
+      note = alloca (sectsize);
+
+      bfd_get_section_contents (abfd, sect, note,
+				(file_ptr) 0, (bfd_size_type) sectsize);
+      
+      name_length = bfd_h_get_32 (abfd, note);
+      data_length = bfd_h_get_32 (abfd, note + 4);
+      note_type   = bfd_h_get_32 (abfd, note + 8);
+
+      if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
+	  && strcmp (note + 12, "NetBSD") == 0)
+	{
+	  /* XXX Should we check the version here?  Probably not
+	     necessary yet.  */
+	  *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
+	}
+      return;
+    }
+}
+
+static enum gdb_osabi
+generic_elf_osabi_sniffer (bfd *abfd)
+{
+  int elfosabi;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
+
+  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+  switch (elfosabi)
+    {
+    case ELFOSABI_NONE:
+      /* When elfosabi is ELFOSABI_NONE (0), this is supposed to indicate
+	 that we're on a SVR4 system.  However, some systems use note sections
+	 to record OS/ABI info, but leave e_ident[EI_OSABI] zero.  So we
+	 have to check the note sections, too.  */
+      bfd_map_over_sections (abfd,
+			     process_note_abi_tag_sections,
+			     &osabi);
+      break;
+
+    case ELFOSABI_FREEBSD:
+      osabi = GDB_OSABI_FREEBSD_ELF;
+      break;
+
+    case ELFOSABI_NETBSD:
+      osabi = GDB_OSABI_NETBSD_ELF;
+      break;
+
+    case ELFOSABI_LINUX:
+      osabi = GDB_OSABI_LINUX;
+      break;
+
+    case ELFOSABI_HURD:
+      osabi = GDB_OSABI_HURD;
+      break;
+
+    case ELFOSABI_SOLARIS:
+      osabi = GDB_OSABI_SOLARIS;
+      break;
+    }
+
+  return osabi;
+}
+\f
+
+void
+_initialize_gdb_osabi (void)
+{
+  /* Register a generic sniffer for ELF flavoured files.  */
+  gdbarch_register_osabi_sniffer (bfd_arch_unknown,
+				  bfd_target_elf_flavour,
+				  generic_elf_osabi_sniffer);
+}
Index: osabi.h
===================================================================
RCS file: osabi.h
diff -N osabi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ osabi.h	12 May 2002 16:43:02 -0000
@@ -0,0 +1,73 @@
+/* OS ABI variant handling for GDB.
+   Copyright 2001, 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef OSABI_H
+#define OSABI_H
+
+/* List of known OS ABIs.  If you change this, make sure to update the
+   table in osabi.c.  */
+enum gdb_osabi
+{
+  GDB_OSABI_UNKNOWN = 0,	/* keep this first */
+
+  GDB_OSABI_SVR4,
+  GDB_OSABI_HURD,
+  GDB_OSABI_SOLARIS,
+  GDB_OSABI_OSF1,
+  GDB_OSABI_LINUX,
+  GDB_OSABI_FREEBSD_AOUT,
+  GDB_OSABI_FREEBSD_ELF,
+  GDB_OSABI_NETBSD_AOUT,
+  GDB_OSABI_NETBSD_ELF,
+  GDB_OSABI_WINCE,
+
+  GDB_OSABI_ARM_EABI_V1,
+  GDB_OSABI_ARM_EABI_V2,
+  GDB_OSABI_ARM_APCS,
+
+  GDB_OSABI_INVALID		/* keep this last */
+};
+
+/* Register an OS ABI sniffer.  Each arch/flavour may have more than
+   one sniffer.  This is used to e.g. differentiate one OS's a.out from
+   another.  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.  */
+void gdbarch_register_osabi_sniffer (enum bfd_architecture,
+				     enum bfd_flavour,
+				     enum gdb_osabi (*)(bfd *));
+
+/* Register a handler for an OS ABI variant for a given architecture.  There
+   should be only one handler for a given OS ABI each architecture family.  */
+void gdbarch_register_osabi (enum bfd_architecture, enum gdb_osabi,
+                             void (*)(struct gdbarch_info,
+				      struct gdbarch *));
+
+/* Lookup the OS ABI corresponding to the specified BFD.  */
+enum gdb_osabi gdbarch_lookup_osabi (bfd *);
+
+/* Initialize the gdbarch for the specified OS ABI variant.  */
+void gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *,
+                         enum gdb_osabi);
+
+/* Return the name of the specified OS ABI.  */
+const char *gdbarch_osabi_name (enum gdb_osabi);
+
+#endif /* OSABI_H */
Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.58
diff -u -r1.58 sh-tdep.c
--- sh-tdep.c	10 May 2002 23:59:09 -0000	1.58
+++ sh-tdep.c	12 May 2002 16:43:06 -0000
@@ -41,6 +41,8 @@
 #include "regcache.h"
 #include "doublest.h"
 
+#include "sh-tdep.h"
+
 #include "elf-bfd.h"
 #include "solib-svr4.h"
 
@@ -4198,175 +4200,6 @@
 #endif /* SVR4_SHARED_LIBS */
 
 \f
-/* This table matches the indices assigned to enum sh_osabi.  Keep
-   them in sync.  */
-static const char * const sh_osabi_names[] =
-{
-  "<unknown>",
-  "GNU/Linux",
-  "NetBSD ELF",
-  NULL
-};
-
-static void
-process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
-{
-  enum sh_osabi *os_ident_ptr = obj;
-  const char *name;
-  unsigned int sectsize;
-
-  name = bfd_get_section_name (abfd, sect);
-  sectsize = bfd_section_size (abfd, sect);
-
-  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, data_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we are
-	 looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
-
-      name_length = bfd_h_get_32 (abfd, note);
-      data_length = bfd_h_get_32 (abfd, note + 4);
-      note_type   = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
-	  && strcmp (note + 12, "GNU") == 0)
-	{
-	  int os_number = bfd_h_get_32 (abfd, note + 16);
-
-	  /* The case numbers are from abi-tags in glibc.  */
-	  switch (os_number)
-	    {
-	    case GNU_ABI_TAG_LINUX:
-	      *os_ident_ptr = SH_OSABI_LINUX;
-	      break;
-
-	    case GNU_ABI_TAG_HURD:
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: Hurd objects not supported");
-	      break;
-
-	    case GNU_ABI_TAG_SOLARIS:
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: Solaris objects not supported");
-	      break;
-
-	    default:
-	      internal_error
-		(__FILE__, __LINE__,
-		 "process_note_abi_sections: unknown OS number %d",
-		 os_number);
-	    }
-	}
-    }
-  /* NetBSD uses a similar trick.  */
-  else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, desc_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we are
-	 looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
-
-      name_length = bfd_h_get_32 (abfd, note);
-      desc_length = bfd_h_get_32 (abfd, note + 4);
-      note_type   = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 7 && desc_length == 4 && note_type == NT_NETBSD_IDENT
-	  && strcmp (note + 12, "NetBSD") == 0)
-	/* XXX Should we check the version here?
-	   Probably not necessary yet.  */
-	*os_ident_ptr = SH_OSABI_NETBSD_ELF;
-    }
-}
-
-static int
-get_elfosabi (bfd *abfd)
-{
-  int elfosabi;
-  enum sh_osabi sh_osabi = SH_OSABI_UNKNOWN;
-
-  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
-
-  switch (elfosabi)
-    {
-    case ELFOSABI_NONE:
-      /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
-	 that we're on a SYSV system.  However, some systems use note sections
-	 to record OS/ABI info, but leave e_ident[EI_OSABI] zero.  So we
-	 have to check the note sections too.  */
-      bfd_map_over_sections (abfd,
-			     process_note_abi_tag_sections,
-			     &sh_osabi);
-      break;
-
-    case ELFOSABI_NETBSD:
-      sh_osabi = SH_OSABI_NETBSD_ELF;
-      break;
-
-    case ELFOSABI_LINUX:
-      sh_osabi = SH_OSABI_LINUX;
-      break;
-    }
-
-  return (sh_osabi);
-}
-
-struct sh_osabi_handler
-{
-  struct sh_osabi_handler *next;
-  enum sh_osabi abi;
-  void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
-};
-
-struct sh_osabi_handler *sh_osabi_handler_list = NULL;
-
-void
-sh_gdbarch_register_os_abi (enum sh_osabi abi,
-                            void (*init_osabi)(struct gdbarch_info,
-					       struct gdbarch *))
-{
-  struct sh_osabi_handler **handler_p;
-
-  for (handler_p = &sh_osabi_handler_list; *handler_p != NULL;
-       handler_p = &(*handler_p)->next)
-    {
-      if ((*handler_p)->abi == abi)
-	{
-	  internal_error
-	    (__FILE__, __LINE__,
-	     "sh_gdbarch_register_os_abi: A handler for this ABI variant "
-	     "(%d) has already been registered", (int) abi);
-	  /* If user wants to continue, override previous definition.  */
-	  (*handler_p)->init_osabi = init_osabi;
-	  return;
-	}
-    }
-
-  (*handler_p)
-    = (struct sh_osabi_handler *) xmalloc (sizeof (struct sh_osabi_handler));
-  (*handler_p)->next = NULL;
-  (*handler_p)->abi = abi;
-  (*handler_p)->init_osabi = init_osabi;
-}
-
 static gdbarch_init_ftype sh_gdbarch_init;
 
 static struct gdbarch *
@@ -4378,23 +4211,14 @@
   gdbarch_register_name_ftype *sh_register_name;
   gdbarch_store_return_value_ftype *sh_store_return_value;
   gdbarch_register_virtual_type_ftype *sh_register_virtual_type;
-  enum sh_osabi sh_osabi = SH_OSABI_UNKNOWN;
-  struct sh_osabi_handler *osabi_handler;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
   /* Try to determine the ABI of the object we are loading.  */
 
   if (info.abfd != NULL)
     {
-      switch (bfd_get_flavour (info.abfd))
-	{
-	case bfd_target_elf_flavour:
-	  sh_osabi = get_elfosabi (info.abfd);
-	  break;
-
-	default:
-	  /* Just leave it as "unkown".  */
-	  break;
-	}
+      osabi = gdbarch_lookup_osabi (info.abfd);
+      /* If we get "unknown" back, just leave it that way.  */
     }
 
   /* Find a candidate among the list of pre-declared architectures. */
@@ -4404,7 +4228,7 @@
     {
       /* Make sure the ABI selection matches.  */
       tdep = gdbarch_tdep (arches->gdbarch);
-      if (tdep && tdep->sh_osabi == sh_osabi)
+      if (tdep && tdep->osabi == osabi)
 	return arches->gdbarch;
     }
 
@@ -4413,15 +4237,7 @@
   tdep = XMALLOC (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
-  tdep->sh_osabi = sh_osabi;
-  if (sh_osabi < SH_OSABI_INVALID)
-    tdep->osabi_name = sh_osabi_names[sh_osabi];
-  else
-    {
-      internal_error (__FILE__, __LINE__, "Invalid setting of sh_osabi %d",
-		      (int) sh_osabi);
-      tdep->osabi_name = "<invalid>";
-    }
+  tdep->osabi = osabi;
 
   /* Initialize the register numbers that are not common to all the
      variants to -1, if necessary thse will be overwritten in the case
@@ -4774,32 +4590,11 @@
   set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
-  /* Hook in ABI-specific overrides, if they have been registered.  If
-     the ABI is unknown, this is probably an embedded target, so we
-     should not warn about this situation.  */
-  if (sh_osabi != SH_OSABI_UNKNOWN)
-    {
-      for (osabi_handler = sh_osabi_handler_list; osabi_handler != NULL;
-	   osabi_handler = osabi_handler->next)
-	if (osabi_handler->abi == sh_osabi)
-	  break;
+  /* Hook in ABI-specific overrides, if they have been registered.
 
-      if (osabi_handler)
-        osabi_handler->init_osabi (info, gdbarch);
-      else
-        {
-	  /* We assume that if GDB_MULTI_ARCH is less than
-	     GDB_MULTI_ARCH_TM that an ABI variant can be supported by 
-	     overriding definitions in this file.  */
-	  if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) 
-	    fprintf_filtered
-	      (gdb_stderr,
-	       "A handler for the ABI variant \"%s\" is not built into this "
-	       "configuration of GDB.  "
-	       "Attempting to continue with the default SuperH settings",
-	       sh_osabi_names[sh_osabi]);
-        }
-    }
+     FIXME: if the ABI is unknown, this is probably an embedded target,
+     so we should not warn about this situation.  */
+  gdbarch_init_osabi (info, gdbarch, osabi);
 
   return gdbarch;
 }
@@ -4812,12 +4607,8 @@
   if (tdep == NULL)
     return;
 
-  if (tdep->osabi_name != NULL)
-    fprintf_unfiltered (file, "sh_dump_tdep: OS ABI = %s\n", tdep->osabi_name);
-  else
-    internal_error (__FILE__, __LINE__,
-		    "sh_dump_tdep: illegal setting of tdep->sh_osabi (%d)",
-		    (int) tdep->sh_osabi);
+  fprintf_unfiltered (file, "sh_dump_tdep: OS ABI = %s\n",
+                      gdbarch_osabi_name (tdep->osabi));
 }
 
 void
Index: sh-tdep.h
===================================================================
RCS file: sh-tdep.h
diff -N sh-tdep.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sh-tdep.h	12 May 2002 16:43:07 -0000
@@ -0,0 +1,111 @@
+/* Target-specific definition for a Hitachi Super-H.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef SH_TDEP_H
+#define SH_TDEP_H
+
+/* Contributed by Steve Chamberlain sac@cygnus.com */
+
+#include "osabi.h"
+
+/* Information that is dependent on the processor variant. */
+
+enum sh_abi
+  {
+    SH_ABI_UNKNOWN,
+    SH_ABI_32,
+    SH_ABI_64
+  };
+
+struct gdbarch_tdep
+  {
+    int PR_REGNUM;
+    int FPUL_REGNUM;  /*                       sh3e, sh4 */
+    int FPSCR_REGNUM; /*                       sh3e, sh4 */
+    int SR_REGNUM;    /* sh-dsp, sh3, sh3-dsp, sh3e, sh4 */
+    int DSR_REGNUM;   /* sh-dsp,      sh3-dsp            */
+    int FP_LAST_REGNUM; /*                     sh3e, sh4 */
+    int A0G_REGNUM;   /* sh-dsp,      sh3-dsp            */
+    int A0_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int A1G_REGNUM;   /* sh-dsp,      sh3-dsp            */
+    int A1_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int M0_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int M1_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int X0_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int X1_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int Y0_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int Y1_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int MOD_REGNUM;   /* sh-dsp,      sh3-dsp            */
+    int SSR_REGNUM;   /*         sh3, sh3-dsp, sh3e, sh4 */
+    int SPC_REGNUM;   /*         sh3, sh3-dsp, sh3e, sh4 */
+    int RS_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int RE_REGNUM;    /* sh-dsp,      sh3-dsp            */
+    int DR0_REGNUM;   /*                             sh4 */
+    int DR_LAST_REGNUM; /*                           sh4 */
+    int FV0_REGNUM;   /*                             sh4 */
+    int FV_LAST_REGNUM; /*                           sh4 */
+    /* FPP stands for Floating Point Pair, to avoid confusion with
+       GDB's FP0_REGNUM, which is the number of the first Floating
+       point register. Unfortunately on the sh5, the floating point
+       registers are called FR, and the floating point pairs are called FP. */
+    int TR7_REGNUM;       /*                            sh5-media*/
+    int FPP0_REGNUM;      /*                            sh5-media*/
+    int FPP_LAST_REGNUM;  /*                            sh5-media*/
+    int R0_C_REGNUM;      /*                            sh5-compact*/
+    int R_LAST_C_REGNUM;  /*                            sh5-compact*/
+    int PC_C_REGNUM;      /*                            sh5-compact*/
+    int GBR_C_REGNUM;     /*                            sh5-compact*/
+    int MACH_C_REGNUM;    /*                            sh5-compact*/
+    int MACL_C_REGNUM;    /*                            sh5-compact*/
+    int PR_C_REGNUM;      /*                            sh5-compact*/
+    int T_C_REGNUM;       /*                            sh5-compact*/
+    int FPSCR_C_REGNUM;   /*                            sh5-compact*/
+    int FPUL_C_REGNUM;    /*                            sh5-compact*/
+    int FP0_C_REGNUM;     /*                            sh5-compact*/
+    int FP_LAST_C_REGNUM; /*                            sh5-compact*/
+    int DR0_C_REGNUM;     /*                            sh5-compact*/
+    int DR_LAST_C_REGNUM; /*                            sh5-compact*/
+    int FV0_C_REGNUM;     /*                            sh5-compact*/
+    int FV_LAST_C_REGNUM; /*                            sh5-compact*/
+    int ARG0_REGNUM;
+    int ARGLAST_REGNUM;
+    int FLOAT_ARGLAST_REGNUM;
+    int RETURN_REGNUM;
+    enum gdb_osabi osabi;      /* OS/ABI of the inferior */
+    enum sh_abi sh_abi;
+  };
+
+/* Registers common to all the SH variants. */
+enum
+  {
+    R0_REGNUM = 0,
+    STRUCT_RETURN_REGNUM = 2,
+    ARG0_REGNUM = 4, /* Used in h8300-tdep.c */
+    ARGLAST_REGNUM = 7, /* Used in h8300-tdep.c */
+    PR_REGNUM = 17, /* used in sh3-rom.c */
+    GBR_REGNUM = 18,
+    VBR_REGNUM = 19,
+    MACH_REGNUM = 20,
+    MACL_REGNUM = 21,
+    SR_REGNUM = 22
+  };
+
+#endif /* SH_TDEP_H */
Index: sh3-rom.c
===================================================================
RCS file: /cvs/src/src/gdb/sh3-rom.c,v
retrieving revision 1.11
diff -u -r1.11 sh3-rom.c
--- sh3-rom.c	15 Jul 2001 20:34:14 -0000	1.11
+++ sh3-rom.c	12 May 2002 16:43:07 -0000
@@ -28,6 +28,8 @@
 #include "arch-utils.h"
 #include "regcache.h"
 
+#include "sh-tdep.h"
+
 static struct serial *parallel;
 static int parallel_in_use;
 
Index: shnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/shnbsd-tdep.c,v
retrieving revision 1.3
diff -u -r1.3 shnbsd-tdep.c
--- shnbsd-tdep.c	11 May 2002 22:14:19 -0000	1.3
+++ shnbsd-tdep.c	12 May 2002 16:43:07 -0000
@@ -25,6 +25,7 @@
 #include "value.h"
 
 #include "nbsd-tdep.h"
+#include "sh-tdep.h"
 #include "shnbsd-tdep.h"
 
 /* Convert an r0-r15 register number into an offset into a ptrace
@@ -176,5 +177,5 @@
   add_core_fns (&shnbsd_core_fns);
   add_core_fns (&shnbsd_elfcore_fns);
 
-  sh_gdbarch_register_os_abi (SH_OSABI_NETBSD_ELF, shnbsd_init_abi);
+  gdbarch_register_osabi (bfd_arch_sh, GDB_OSABI_NETBSD_ELF, shnbsd_init_abi);
 }
Index: config/sh/tm-sh.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v
retrieving revision 1.18
diff -u -r1.18 tm-sh.h
--- config/sh/tm-sh.h	10 May 2002 23:00:23 -0000	1.18
+++ config/sh/tm-sh.h	12 May 2002 16:43:08 -0000
@@ -23,100 +23,6 @@
 
 #define GDB_MULTI_ARCH 1
 
-/* Information that is dependent on the processor variant. */
-
-/* ABI variants that we know about.  If you add to this enum, please
-   update the table of names in sh-tdep.c.  */
-enum sh_osabi
-{
-  SH_OSABI_UNKNOWN = 0,
-  SH_OSABI_LINUX,
-  SH_OSABI_NETBSD_ELF,
-
-  SH_OSABI_INVALID     /* Keep this last.  */
-};
-
-enum sh_abi
-  {
-    SH_ABI_UNKNOWN,
-    SH_ABI_32,
-    SH_ABI_64
-  };
-
-struct gdbarch_tdep
-  {
-    int PR_REGNUM;
-    int FPUL_REGNUM;  /*                       sh3e, sh4 */
-    int FPSCR_REGNUM; /*                       sh3e, sh4 */
-    int SR_REGNUM;    /* sh-dsp, sh3, sh3-dsp, sh3e, sh4 */
-    int DSR_REGNUM;   /* sh-dsp,      sh3-dsp            */
-    int FP_LAST_REGNUM; /*                     sh3e, sh4 */
-    int A0G_REGNUM;   /* sh-dsp,      sh3-dsp            */
-    int A0_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int A1G_REGNUM;   /* sh-dsp,      sh3-dsp            */
-    int A1_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int M0_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int M1_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int X0_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int X1_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int Y0_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int Y1_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int MOD_REGNUM;   /* sh-dsp,      sh3-dsp            */
-    int SSR_REGNUM;   /*         sh3, sh3-dsp, sh3e, sh4 */
-    int SPC_REGNUM;   /*         sh3, sh3-dsp, sh3e, sh4 */
-    int RS_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int RE_REGNUM;    /* sh-dsp,      sh3-dsp            */
-    int DR0_REGNUM;   /*                             sh4 */
-    int DR_LAST_REGNUM; /*                           sh4 */
-    int FV0_REGNUM;   /*                             sh4 */
-    int FV_LAST_REGNUM; /*                           sh4 */
-    /* FPP stands for Floating Point Pair, to avoid confusion with
-       GDB's FP0_REGNUM, which is the number of the first Floating
-       point register. Unfortunately on the sh5, the floating point
-       registers are called FR, and the floating point pairs are called FP. */
-    int TR7_REGNUM;       /*                            sh5-media*/
-    int FPP0_REGNUM;      /*                            sh5-media*/
-    int FPP_LAST_REGNUM;  /*                            sh5-media*/
-    int R0_C_REGNUM;      /*                            sh5-compact*/
-    int R_LAST_C_REGNUM;  /*                            sh5-compact*/
-    int PC_C_REGNUM;      /*                            sh5-compact*/
-    int GBR_C_REGNUM;     /*                            sh5-compact*/
-    int MACH_C_REGNUM;    /*                            sh5-compact*/
-    int MACL_C_REGNUM;    /*                            sh5-compact*/
-    int PR_C_REGNUM;      /*                            sh5-compact*/
-    int T_C_REGNUM;       /*                            sh5-compact*/
-    int FPSCR_C_REGNUM;   /*                            sh5-compact*/
-    int FPUL_C_REGNUM;    /*                            sh5-compact*/
-    int FP0_C_REGNUM;     /*                            sh5-compact*/
-    int FP_LAST_C_REGNUM; /*                            sh5-compact*/
-    int DR0_C_REGNUM;     /*                            sh5-compact*/
-    int DR_LAST_C_REGNUM; /*                            sh5-compact*/
-    int FV0_C_REGNUM;     /*                            sh5-compact*/
-    int FV_LAST_C_REGNUM; /*                            sh5-compact*/
-    int ARG0_REGNUM;
-    int ARGLAST_REGNUM;
-    int FLOAT_ARGLAST_REGNUM;
-    int RETURN_REGNUM;
-    enum sh_osabi sh_osabi;    /* OS/ABI of the inferior */
-    const char *osabi_name;    /* Name of the above */
-    enum sh_abi sh_abi;
-  };
-
-/* Registers common to all the SH variants. */
-enum
-  {
-    R0_REGNUM = 0,
-    STRUCT_RETURN_REGNUM = 2,
-    ARG0_REGNUM = 4, /* Used in h8300-tdep.c */
-    ARGLAST_REGNUM = 7, /* Used in h8300-tdep.c */
-    PR_REGNUM = 17, /* used in sh3-rom.c */
-    GBR_REGNUM = 18,
-    VBR_REGNUM = 19,
-    MACH_REGNUM = 20,
-    MACL_REGNUM = 21,
-    SR_REGNUM = 22
-  };
-
 #define NUM_REALREGS 59 /* used in remote-e7000.c which is not multiarched. */
 
 #define REGISTER_TYPE  long /* used in standalone.c */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-12 10:06 ` Jason R Thorpe
@ 2002-05-12 21:50   ` Eli Zaretskii
  2002-05-12 22:00     ` Jason R Thorpe
  0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2002-05-12 21:50 UTC (permalink / raw)
  To: Jason R Thorpe; +Cc: gdb-patches


On Sun, 12 May 2002, Jason R Thorpe wrote:

> On Sat, May 11, 2002 at 09:20:46PM -0700, Jason R Thorpe wrote:
> 
>  > Tomorrow I'll make the Alpha and SH targets use the generic OS ABI
>  > framework as examples.
> 
> Ok, as promised.

Thanks.

If this is approved, may I suggest to document this framework in 
gdbint.texinfo?


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-12 21:50   ` Eli Zaretskii
@ 2002-05-12 22:00     ` Jason R Thorpe
  2002-05-12 22:27       ` Eli Zaretskii
  0 siblings, 1 reply; 9+ messages in thread
From: Jason R Thorpe @ 2002-05-12 22:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On Mon, May 13, 2002 at 07:48:34AM +0300, Eli Zaretskii wrote:

 > If this is approved, may I suggest to document this framework in 
 > gdbint.texinfo?

Yes, that is the plan.  I'll submit a patch for the documentation
tomorrow (with luck :-)

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-11 21:20 [PATCH/RFC] Generic OS ABI handling for gdbarch Jason R Thorpe
  2002-05-12 10:06 ` Jason R Thorpe
@ 2002-05-12 22:20 ` Andrew Cagney
  2002-05-13  8:49   ` Jason R Thorpe
  1 sibling, 1 reply; 9+ messages in thread
From: Andrew Cagney @ 2002-05-12 22:20 UTC (permalink / raw)
  To: thorpej; +Cc: gdb-patches

> I started working on generic OS ABI handling for GDB today, lifting from
> the various duplicated bits of code in several targets.
> 
> There are two pieces to the generic code:
> 
> 	* OS ABI handlers.  These are basically the same as the OS ABI
> 	  handlers that exist on a per-target basis, but when they're
> 	  registered, you now specify a bfd_architecture.  Only one
> 	  OS ABI can exist per bfd_architecture.
> 
> 	* OS ABI "sniffers".  These peek at a BFD with a given
> 	  bfd_architecture/bfd_flavour and determine which OS ABI
> 	  is correct for that BFD.  Multiple sniffers can exist for
> 	  a given bfd_architecture/bfd_flavour, e.g. one to sniff out
> 	  NetBSD a.out, one for FreeBSD a.out, etc.  If a sniffer
> 	  registers w/ bfd_architecture of "unknown", it can sniff
> 	  files of any architecture for its flavour.
> 
> 	  There is a generic ELF sniffer that uses EI_OSABI and note
> 	  sections.  (This is an example of an arch == "unknown"
> 	  sniffer.)
> 
> 	  The first sniffer to return other than GDB_OSABI_UNKNOWN
> 	  wins, so sniffers should be careful to only claim BFDs
> 	  they're sure about.
> 
> Tomorrow I'll make the Alpha and SH targets use the generic OS ABI
> framework as examples.

Yep, by me.  And the target maintainers (arm, we're obsoleting WinCE), 
perhaphs give it some of the week to stew.

Andrew

> +#ifndef OSABI_H
> +#define OSABI_H

struct gdbarch;
[Hmm, the include section of the doco, doesn't mention this.]

> +/* List of known OS ABIs.  If you change this, make sure to update the
> +   table in osabi.c.  */

Suggest checking this in _initialize_osabi().

> +enum gdb_osabi
> +{
> +  GDB_OSABI_UNKNOWN = 0,	/* keep this first */

> +
> +/* Register an OS ABI sniffer.  Each arch/flavour may have more than
> +   one sniffer.  This is used to e.g. differentiate one OS's a.out from
> +   another.  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.  */

What is the overhead of the ``sniff test''?  Can I suggest checking all 
regardless and then internal_error()ing on a double hit.

In the one hand, this means looking for trouble.  On the other hand, it 
is the only way we'll flush out some bugs before the next release.

nice,
Andrew



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-12 22:00     ` Jason R Thorpe
@ 2002-05-12 22:27       ` Eli Zaretskii
  0 siblings, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2002-05-12 22:27 UTC (permalink / raw)
  To: Jason R Thorpe; +Cc: gdb-patches


On Sun, 12 May 2002, Jason R Thorpe wrote:

>  > If this is approved, may I suggest to document this framework in 
>  > gdbint.texinfo?
> 
> Yes, that is the plan.  I'll submit a patch for the documentation
> tomorrow (with luck :-)

Thanks!


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-12 22:20 ` Andrew Cagney
@ 2002-05-13  8:49   ` Jason R Thorpe
  2002-05-13  9:10     ` Andrew Cagney
  0 siblings, 1 reply; 9+ messages in thread
From: Jason R Thorpe @ 2002-05-13  8:49 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Mon, May 13, 2002 at 01:20:07AM -0400, Andrew Cagney wrote:

 > > +/* List of known OS ABIs.  If you change this, make sure to update the
 > > +   table in osabi.c.  */
 > 
 > Suggest checking this in _initialize_osabi().

Ok.  Sufficient to check that the last one is NULL?

 > What is the overhead of the ``sniff test''?  Can I suggest checking all 
 > regardless and then internal_error()ing on a double hit.
 > 
 > In the one hand, this means looking for trouble.  On the other hand, it 
 > is the only way we'll flush out some bugs before the next release.

I don't think the overhead is that much.  I mean, it only happens once
at the start of the debugging session, anyway, and I think sniffing the
BFD is going to be a lot faster than loading the symbol table of most
things, anyway :-)

So, I'll make this tweak, as well.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-13  8:49   ` Jason R Thorpe
@ 2002-05-13  9:10     ` Andrew Cagney
  2002-05-13  9:13       ` Jason R Thorpe
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew Cagney @ 2002-05-13  9:10 UTC (permalink / raw)
  To: thorpej; +Cc: gdb-patches

>> > +/* List of known OS ABIs.  If you change this, make sure to update the
>  > > +   table in osabi.c.  */
>  > 
>  > Suggest checking this in _initialize_osabi().
> 
> Ok.  Sufficient to check that the last one is NULL?

Sure, thanks!.

Andrew




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH/RFC] Generic OS ABI handling for gdbarch
  2002-05-13  9:10     ` Andrew Cagney
@ 2002-05-13  9:13       ` Jason R Thorpe
  0 siblings, 0 replies; 9+ messages in thread
From: Jason R Thorpe @ 2002-05-13  9:13 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Mon, May 13, 2002 at 12:10:08PM -0400, Andrew Cagney wrote:

 > > Ok.  Sufficient to check that the last one is NULL?
 > 
 > Sure, thanks!.

Actually, it occured to me that could be error-prone (what if you
happen to run off the array and into another memory location that
happens to contain 0? :-)

I'll post another patch shortly.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2002-05-13 16:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-11 21:20 [PATCH/RFC] Generic OS ABI handling for gdbarch Jason R Thorpe
2002-05-12 10:06 ` Jason R Thorpe
2002-05-12 21:50   ` Eli Zaretskii
2002-05-12 22:00     ` Jason R Thorpe
2002-05-12 22:27       ` Eli Zaretskii
2002-05-12 22:20 ` Andrew Cagney
2002-05-13  8:49   ` Jason R Thorpe
2002-05-13  9:10     ` Andrew Cagney
2002-05-13  9:13       ` Jason R Thorpe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox