Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
@ 2002-05-07  1:45 Jason R Thorpe
  2002-05-07  8:18 ` Elena Zannoni
  0 siblings, 1 reply; 6+ messages in thread
From: Jason R Thorpe @ 2002-05-07  1:45 UTC (permalink / raw)
  To: gdb-patches

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

The following adds OS/ABI handling a'la the ARM and Alpha targets
to the SuperH target.

Once this is in, I'll be able to commit my NetBSD/sh variant.

OK to commit?

	* sh-tdep.c (sh_abi_names): Declare.
	(process_note_abi_tag_sections): New function.
	(get_elfosabi): Ditto.
	(sh_gdbarch_register_os_abi): Ditto.
	(sh_dump_tdep): Ditto.
	(_initialize_sh_tdep): Use gdbarch_register to register
	sh_gdbarch_init and sh_dump_tdep.
	* config/sh/tm-sh.h (sh_abi): Declare.
	(gdbarch_tdep): Add sh_abi and abi_name members.

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

[-- Attachment #2: sh-abi-patch --]
[-- Type: text/plain, Size: 9725 bytes --]

Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.52
diff -u -r1.52 sh-tdep.c
--- sh-tdep.c	12 Apr 2002 18:18:57 -0000	1.52
+++ sh-tdep.c	7 May 2002 08:21:59 -0000
@@ -41,6 +41,8 @@
 #include "regcache.h"
 #include "doublest.h"
 
+#include "elf-bfd.h"
+
 #include "solib-svr4.h"
 
 void (*sh_show_regs) (void);
@@ -1895,6 +1897,182 @@
 }
 #endif /* SVR4_SHARED_LIBS */
 
+\f
+/* This table matches the indices assigned to enum sh_abi.  Keep
+   them in sync.  */
+static const char * const sh_abi_names[] =
+{
+  "<unknown>",
+  "GNU/Linux",
+  "NetBSD ELF",
+  NULL
+};
+
+static void
+process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+{
+  enum sh_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 = SH_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);
+	    }
+	}
+    }
+  /* 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 = SH_ABI_NETBSD_ELF;
+    }
+}
+
+static int
+get_elfosabi (bfd *abfd)
+{
+  int elfosabi;
+  enum sh_abi sh_abi = SH_ABI_UNKNOWN;
+
+  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
+
+  /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
+     that 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,
+			     &sh_abi);
+    }
+
+  if (sh_abi != SH_ABI_UNKNOWN)
+    return sh_abi;
+
+  switch (elfosabi)
+    {
+    case ELFOSABI_NONE:
+      /* Leave it as unknown.  */
+      break;
+
+    case ELFOSABI_NETBSD:
+      return SH_ABI_NETBSD_ELF;
+
+    case ELFOSABI_LINUX:
+      return SH_ABI_LINUX;
+    }
+
+  return SH_ABI_UNKNOWN;
+}
+
+struct sh_abi_handler
+{
+  struct sh_abi_handler *next;
+  enum sh_abi abi;
+  void (*init_abi)(struct gdbarch_info, struct gdbarch *);
+};
+
+struct sh_abi_handler *sh_abi_handler_list = NULL;
+
+void
+sh_gdbarch_register_os_abi (enum sh_abi abi,
+                            void (*init_abi)(struct gdbarch_info,
+					     struct gdbarch *))
+{
+  struct sh_abi_handler **handler_p;
+
+  for (handler_p = &sh_abi_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_abi = init_abi;
+	  return;
+	}
+    }
+
+  (*handler_p)
+    = (struct sh_abi_handler *) xmalloc (sizeof (struct sh_abi_handler));
+  (*handler_p)->next = NULL;
+  (*handler_p)->abi = abi;
+  (*handler_p)->init_abi = init_abi;
+}
+
 static gdbarch_init_ftype sh_gdbarch_init;
 
 static struct gdbarch *
@@ -1906,17 +2084,51 @@
   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_abi sh_abi = SH_ABI_UNKNOWN;
+  struct sh_abi_handler *abi_handler;
+
+  /* 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_abi = get_elfosabi (info.abfd);
+	  break;
+
+	default:
+	  /* Just leave it as "unkown".  */
+	  break;
+	}
+    }
 
   /* Find a candidate among the list of pre-declared architectures. */
-  arches = gdbarch_list_lookup_by_info (arches, &info);
-  if (arches != NULL)
-    return arches->gdbarch;
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      /* Make sure the ABI selection matches.  */
+      tdep = gdbarch_tdep (arches->gdbarch);
+      if (tdep && tdep->sh_abi == sh_abi)
+	return arches->gdbarch;
+    }
 
   /* None found, create a new architecture from the information
      provided. */
   tdep = XMALLOC (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
+  tdep->sh_abi = sh_abi;
+  if (sh_abi < SH_ABI_INVALID)
+    tdep->abi_name = sh_abi_names[sh_abi];
+  else
+    {
+      internal_error (__FILE__, __LINE__, "Invalid setting of sh_abi %d",
+		      (int) sh_abi);
+      tdep->abi_name = "<invalid>";
+    }
+
   /* Initialize the register numbers that are not common to all the
      variants to -1, if necessary thse will be overwritten in the case
      statement below. */
@@ -2167,15 +2379,58 @@
   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_abi != SH_ABI_UNKNOWN)
+    {
+      for (abi_handler = sh_abi_handler_list; abi_handler != NULL;
+	   abi_handler = abi_handler->next)
+	if (abi_handler->abi == sh_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 SuperH settings",
+	       sh_abi_names[sh_abi]);
+        }
+    }
+
   return gdbarch;
 }
 
+static void
+sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  if (tdep == NULL)
+    return;
+
+  if (tdep->abi_name != NULL)
+    fprintf_unfiltered (file, "sh_dump_tdep: ABI = %s\n", tdep->abi_name);
+  else
+    internal_error (__FILE__, __LINE__,
+		    "sh_dump_tdep: illegal setting of tdep->sh_abi (%d)",
+		    (int) tdep->sh_abi);
+}
+
 void
 _initialize_sh_tdep (void)
 {
   struct cmd_list_element *c;
   
-  register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init);
+  gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
 
   add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 }
Index: config/sh/tm-sh.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v
retrieving revision 1.16
diff -u -r1.16 tm-sh.h
--- config/sh/tm-sh.h	12 Jul 2001 02:29:33 -0000	1.16
+++ config/sh/tm-sh.h	7 May 2002 08:22:00 -0000
@@ -23,6 +23,17 @@
 
 #define GDB_MULTI_ARCH 1
 
+/* ABI variants that we know about.  If you add to this enum, please
+   update the table of names in sh-tdep.c.  */
+enum sh_abi
+{
+  SH_ABI_UNKNOWN = 0,
+  SH_ABI_LINUX,
+  SH_ABI_NETBSD_ELF,
+
+  SH_ABI_INVALID	/* Keep this last.  */
+};
+
 /* Information that is dependent on the processor variant. */
 
 struct gdbarch_tdep
@@ -56,6 +67,9 @@
     int ARGLAST_REGNUM;
     int FLOAT_ARGLAST_REGNUM;
     int RETURN_REGNUM;
+
+    enum sh_abi sh_abi;		/* OS/ABI of the inferior */
+    const char *abi_name;	/* Name of the above */
   };
 
 /* Registers common to all the SH variants. */
@@ -81,4 +95,3 @@
 #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
 
 /*#define NOP   {0x20, 0x0b}*/ /* Who uses this???*/
-

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

* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
  2002-05-07  1:45 [PATCH/RFA] Add OS/ABI infrastructure to SuperH target Jason R Thorpe
@ 2002-05-07  8:18 ` Elena Zannoni
  2002-05-07  9:29   ` Jason R Thorpe
  2002-05-07 13:31   ` Jason R Thorpe
  0 siblings, 2 replies; 6+ messages in thread
From: Elena Zannoni @ 2002-05-07  8:18 UTC (permalink / raw)
  To: thorpej; +Cc: gdb-patches

Jason R Thorpe writes:
 > The following adds OS/ABI handling a'la the ARM and Alpha targets
 > to the SuperH target.
 > 
 > Once this is in, I'll be able to commit my NetBSD/sh variant.
 > 
 > OK to commit?
 > 
 > 	* sh-tdep.c (sh_abi_names): Declare.
 > 	(process_note_abi_tag_sections): New function.
 > 	(get_elfosabi): Ditto.
 > 	(sh_gdbarch_register_os_abi): Ditto.
 > 	(sh_dump_tdep): Ditto.
 > 	(_initialize_sh_tdep): Use gdbarch_register to register
 > 	sh_gdbarch_init and sh_dump_tdep.
 > 	* config/sh/tm-sh.h (sh_abi): Declare.
 > 	(gdbarch_tdep): Add sh_abi and abi_name members.
 > 

Ah, great! But hmmm...it would be ok, except that I am afraid there
may be some conflict with the sh5 work. In there I defined:

enum sh_abi
  {
    SH_ABI_UNKNOWN,
    SH_ABI_32,
    SH_ABI_64
  };

The ABI is unknown for all the architectures except for sh5 where it
is set to either 32 or 64 depending on the bfd. I am not saying this
is completely correct, note.

Is there any chance you could take a look at the sh5 patch I posted a
while back, and see if/how your patch integrates (in principle, at least)?
The patch is here:
http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html

About your patch, I would prefer if the switch on the os_number used
names instead of 0,1,2, is this possible? Same for this line:
+  if (elfosabi == 0)

thanks
Elena


 > -- 
 >         -- Jason R. Thorpe <thorpej@wasabisystems.com>
 > Index: sh-tdep.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/sh-tdep.c,v
 > retrieving revision 1.52
 > diff -u -r1.52 sh-tdep.c
 > --- sh-tdep.c	12 Apr 2002 18:18:57 -0000	1.52
 > +++ sh-tdep.c	7 May 2002 08:21:59 -0000
 > @@ -41,6 +41,8 @@
 >  #include "regcache.h"
 >  #include "doublest.h"
 >  
 > +#include "elf-bfd.h"
 > +
 >  #include "solib-svr4.h"
 >  
 >  void (*sh_show_regs) (void);
 > @@ -1895,6 +1897,182 @@
 >  }
 >  #endif /* SVR4_SHARED_LIBS */
 >  
 > +\f
 > +/* This table matches the indices assigned to enum sh_abi.  Keep
 > +   them in sync.  */
 > +static const char * const sh_abi_names[] =
 > +{
 > +  "<unknown>",
 > +  "GNU/Linux",
 > +  "NetBSD ELF",
 > +  NULL
 > +};
 > +
 > +static void
 > +process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
 > +{
 > +  enum sh_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 = SH_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);
 > +	    }
 > +	}
 > +    }
 > +  /* 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 = SH_ABI_NETBSD_ELF;
 > +    }
 > +}
 > +
 > +static int
 > +get_elfosabi (bfd *abfd)
 > +{
 > +  int elfosabi;
 > +  enum sh_abi sh_abi = SH_ABI_UNKNOWN;
 > +
 > +  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
 > +
 > +  /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
 > +     that 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,
 > +			     &sh_abi);
 > +    }
 > +
 > +  if (sh_abi != SH_ABI_UNKNOWN)
 > +    return sh_abi;
 > +
 > +  switch (elfosabi)
 > +    {
 > +    case ELFOSABI_NONE:
 > +      /* Leave it as unknown.  */
 > +      break;
 > +
 > +    case ELFOSABI_NETBSD:
 > +      return SH_ABI_NETBSD_ELF;
 > +
 > +    case ELFOSABI_LINUX:
 > +      return SH_ABI_LINUX;
 > +    }
 > +
 > +  return SH_ABI_UNKNOWN;
 > +}
 > +
 > +struct sh_abi_handler
 > +{
 > +  struct sh_abi_handler *next;
 > +  enum sh_abi abi;
 > +  void (*init_abi)(struct gdbarch_info, struct gdbarch *);
 > +};
 > +
 > +struct sh_abi_handler *sh_abi_handler_list = NULL;
 > +
 > +void
 > +sh_gdbarch_register_os_abi (enum sh_abi abi,
 > +                            void (*init_abi)(struct gdbarch_info,
 > +					     struct gdbarch *))
 > +{
 > +  struct sh_abi_handler **handler_p;
 > +
 > +  for (handler_p = &sh_abi_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_abi = init_abi;
 > +	  return;
 > +	}
 > +    }
 > +
 > +  (*handler_p)
 > +    = (struct sh_abi_handler *) xmalloc (sizeof (struct sh_abi_handler));
 > +  (*handler_p)->next = NULL;
 > +  (*handler_p)->abi = abi;
 > +  (*handler_p)->init_abi = init_abi;
 > +}
 > +
 >  static gdbarch_init_ftype sh_gdbarch_init;
 >  
 >  static struct gdbarch *
 > @@ -1906,17 +2084,51 @@
 >    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_abi sh_abi = SH_ABI_UNKNOWN;
 > +  struct sh_abi_handler *abi_handler;
 > +
 > +  /* 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_abi = get_elfosabi (info.abfd);
 > +	  break;
 > +
 > +	default:
 > +	  /* Just leave it as "unkown".  */
 > +	  break;
 > +	}
 > +    }
 >  
 >    /* Find a candidate among the list of pre-declared architectures. */
 > -  arches = gdbarch_list_lookup_by_info (arches, &info);
 > -  if (arches != NULL)
 > -    return arches->gdbarch;
 > +  for (arches = gdbarch_list_lookup_by_info (arches, &info);
 > +       arches != NULL;
 > +       arches = gdbarch_list_lookup_by_info (arches->next, &info))
 > +    {
 > +      /* Make sure the ABI selection matches.  */
 > +      tdep = gdbarch_tdep (arches->gdbarch);
 > +      if (tdep && tdep->sh_abi == sh_abi)
 > +	return arches->gdbarch;
 > +    }
 >  
 >    /* None found, create a new architecture from the information
 >       provided. */
 >    tdep = XMALLOC (struct gdbarch_tdep);
 >    gdbarch = gdbarch_alloc (&info, tdep);
 >  
 > +  tdep->sh_abi = sh_abi;
 > +  if (sh_abi < SH_ABI_INVALID)
 > +    tdep->abi_name = sh_abi_names[sh_abi];
 > +  else
 > +    {
 > +      internal_error (__FILE__, __LINE__, "Invalid setting of sh_abi %d",
 > +		      (int) sh_abi);
 > +      tdep->abi_name = "<invalid>";
 > +    }
 > +
 >    /* Initialize the register numbers that are not common to all the
 >       variants to -1, if necessary thse will be overwritten in the case
 >       statement below. */
 > @@ -2167,15 +2379,58 @@
 >    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_abi != SH_ABI_UNKNOWN)
 > +    {
 > +      for (abi_handler = sh_abi_handler_list; abi_handler != NULL;
 > +	   abi_handler = abi_handler->next)
 > +	if (abi_handler->abi == sh_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 SuperH settings",
 > +	       sh_abi_names[sh_abi]);
 > +        }
 > +    }
 > +
 >    return gdbarch;
 >  }
 >  
 > +static void
 > +sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 > +{
 > +  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 > +
 > +  if (tdep == NULL)
 > +    return;
 > +
 > +  if (tdep->abi_name != NULL)
 > +    fprintf_unfiltered (file, "sh_dump_tdep: ABI = %s\n", tdep->abi_name);
 > +  else
 > +    internal_error (__FILE__, __LINE__,
 > +		    "sh_dump_tdep: illegal setting of tdep->sh_abi (%d)",
 > +		    (int) tdep->sh_abi);
 > +}
 > +
 >  void
 >  _initialize_sh_tdep (void)
 >  {
 >    struct cmd_list_element *c;
 >    
 > -  register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init);
 > +  gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
 >  
 >    add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 >  }
 > Index: config/sh/tm-sh.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v
 > retrieving revision 1.16
 > diff -u -r1.16 tm-sh.h
 > --- config/sh/tm-sh.h	12 Jul 2001 02:29:33 -0000	1.16
 > +++ config/sh/tm-sh.h	7 May 2002 08:22:00 -0000
 > @@ -23,6 +23,17 @@
 >  
 >  #define GDB_MULTI_ARCH 1
 >  
 > +/* ABI variants that we know about.  If you add to this enum, please
 > +   update the table of names in sh-tdep.c.  */
 > +enum sh_abi
 > +{
 > +  SH_ABI_UNKNOWN = 0,
 > +  SH_ABI_LINUX,
 > +  SH_ABI_NETBSD_ELF,
 > +
 > +  SH_ABI_INVALID	/* Keep this last.  */
 > +};
 > +
 >  /* Information that is dependent on the processor variant. */
 >  
 >  struct gdbarch_tdep
 > @@ -56,6 +67,9 @@
 >      int ARGLAST_REGNUM;
 >      int FLOAT_ARGLAST_REGNUM;
 >      int RETURN_REGNUM;
 > +
 > +    enum sh_abi sh_abi;		/* OS/ABI of the inferior */
 > +    const char *abi_name;	/* Name of the above */
 >    };
 >  
 >  /* Registers common to all the SH variants. */
 > @@ -81,4 +95,3 @@
 >  #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
 >  
 >  /*#define NOP   {0x20, 0x0b}*/ /* Who uses this???*/
 > -


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

* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
  2002-05-07  8:18 ` Elena Zannoni
@ 2002-05-07  9:29   ` Jason R Thorpe
  2002-05-07 13:31   ` Jason R Thorpe
  1 sibling, 0 replies; 6+ messages in thread
From: Jason R Thorpe @ 2002-05-07  9:29 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb-patches

On Tue, May 07, 2002 at 11:18:01AM -0400, Elena Zannoni wrote:

 > The ABI is unknown for all the architectures except for sh5 where it
 > is set to either 32 or 64 depending on the bfd. I am not saying this
 > is completely correct, note.

Hm.  Well, I'm happy to change the OS/ABI stuff to "sh_osabi".  Might be
more appropriate, anyway (eventually, I want to make the osabi stuff generic
and plop it into a common file).

 > Is there any chance you could take a look at the sh5 patch I posted a
 > while back, and see if/how your patch integrates (in principle, at least)?
 > The patch is here:
 > http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html

Yah, I'll peek at it in a couple of hours.

 > About your patch, I would prefer if the switch on the os_number used
 > names instead of 0,1,2, is this possible? Same for this line:
 > +  if (elfosabi == 0)

Hm, are there manifest constants defined in our header files for the
GNU OS numbers?  Heh, if not, I guess it wouldn't be hard to add them :-)

Anyway, I'll tweak this in a bit and re-post.

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


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

* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
  2002-05-07  8:18 ` Elena Zannoni
  2002-05-07  9:29   ` Jason R Thorpe
@ 2002-05-07 13:31   ` Jason R Thorpe
  2002-05-07 13:35     ` Elena Zannoni
  1 sibling, 1 reply; 6+ messages in thread
From: Jason R Thorpe @ 2002-05-07 13:31 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb-patches

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

On Tue, May 07, 2002 at 11:18:01AM -0400, Elena Zannoni wrote:

 > Is there any chance you could take a look at the sh5 patch I posted a
 > while back, and see if/how your patch integrates (in principle, at least)?
 > The patch is here:
 > http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html

I looked over this patch -- with my rename of "sh_abi" to "sh_osabi", I
don't really see any conflict (SHcompact vs. SHmedia [32 vs 64] seems
orthogonal to OS ABI variations -- sort of like ARM vs. Thumb and Linux
vs. NetBSD).

 > About your patch, I would prefer if the switch on the os_number used
 > names instead of 0,1,2, is this possible? Same for this line:
 > +  if (elfosabi == 0)

...also made these suggested changes, and submitted the patch that defines
the constants to binutils for approval (err, did I follow protocol correctly
in doing so?)

Anyway, updated patch attached.  OK to commit once the elf/common.h patch
goes in?

	* sh-tdep.c (sh_osabi_names): Declare.
	(process_note_abi_tag_sections): New function.
	(get_elfosabi): Ditto.
	(sh_gdbarch_register_os_abi): Ditto.
	(sh_dump_tdep): Ditto.
	_initialize_sh_tdep): Use gdbarch_register to register
	sh_gdbarch_init and sh_dump_tdep.
	* config/sh/tm-sh.h (sh_osabi): Declare.
	(gdbarch_tdep): Add sh_osabi and osabi_name members.

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

[-- Attachment #2: sh-abi-patch --]
[-- Type: text/plain, Size: 9843 bytes --]

Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.52
diff -u -r1.52 sh-tdep.c
--- sh-tdep.c	12 Apr 2002 18:18:57 -0000	1.52
+++ sh-tdep.c	7 May 2002 20:19:36 -0000
@@ -41,6 +41,8 @@
 #include "regcache.h"
 #include "doublest.h"
 
+#include "elf-bfd.h"
+
 #include "solib-svr4.h"
 
 void (*sh_show_regs) (void);
@@ -1895,6 +1897,176 @@
 }
 #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 *
@@ -1906,17 +2078,51 @@
   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;
+
+  /* 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;
+	}
+    }
 
   /* Find a candidate among the list of pre-declared architectures. */
-  arches = gdbarch_list_lookup_by_info (arches, &info);
-  if (arches != NULL)
-    return arches->gdbarch;
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      /* Make sure the ABI selection matches.  */
+      tdep = gdbarch_tdep (arches->gdbarch);
+      if (tdep && tdep->sh_osabi == sh_osabi)
+	return arches->gdbarch;
+    }
 
   /* None found, create a new architecture from the information
      provided. */
   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>";
+    }
+
   /* Initialize the register numbers that are not common to all the
      variants to -1, if necessary thse will be overwritten in the case
      statement below. */
@@ -2167,15 +2373,58 @@
   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;
+
+      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]);
+        }
+    }
+
   return gdbarch;
 }
 
+static void
+sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  if (tdep == NULL)
+    return;
+
+  if (tdep->osabi_name != NULL)
+    fprintf_unfiltered (file, "sh_dump_tdep: 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);
+}
+
 void
 _initialize_sh_tdep (void)
 {
   struct cmd_list_element *c;
   
-  register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init);
+  gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
 
   add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 }
Index: config/sh/tm-sh.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v
retrieving revision 1.16
diff -u -r1.16 tm-sh.h
--- config/sh/tm-sh.h	12 Jul 2001 02:29:33 -0000	1.16
+++ config/sh/tm-sh.h	7 May 2002 20:19:36 -0000
@@ -23,6 +23,17 @@
 
 #define GDB_MULTI_ARCH 1
 
+/* 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.  */
+};
+
 /* Information that is dependent on the processor variant. */
 
 struct gdbarch_tdep
@@ -56,6 +67,9 @@
     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 */
   };
 
 /* Registers common to all the SH variants. */
@@ -81,4 +95,3 @@
 #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
 
 /*#define NOP   {0x20, 0x0b}*/ /* Who uses this???*/
-

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

* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
  2002-05-07 13:31   ` Jason R Thorpe
@ 2002-05-07 13:35     ` Elena Zannoni
  2002-05-08  7:54       ` Jason R Thorpe
  0 siblings, 1 reply; 6+ messages in thread
From: Elena Zannoni @ 2002-05-07 13:35 UTC (permalink / raw)
  To: thorpej; +Cc: Elena Zannoni, gdb-patches

Jason R Thorpe writes:
 > On Tue, May 07, 2002 at 11:18:01AM -0400, Elena Zannoni wrote:
 > 
 >  > Is there any chance you could take a look at the sh5 patch I posted a
 >  > while back, and see if/how your patch integrates (in principle, at least)?
 >  > The patch is here:
 >  > http://sources.redhat.com/ml/gdb-patches/2002-02/msg00218.html
 > 
 > I looked over this patch -- with my rename of "sh_abi" to "sh_osabi", I
 > don't really see any conflict (SHcompact vs. SHmedia [32 vs 64] seems
 > orthogonal to OS ABI variations -- sort of like ARM vs. Thumb and Linux
 > vs. NetBSD).
 > 

Cool, thanks.

 >  > About your patch, I would prefer if the switch on the os_number used
 >  > names instead of 0,1,2, is this possible? Same for this line:
 >  > +  if (elfosabi == 0)
 > 
 > ...also made these suggested changes, and submitted the patch that defines
 > the constants to binutils for approval (err, did I follow protocol correctly
 > in doing so?)
 > 

Yes, I think so.

 > Anyway, updated patch attached.  OK to commit once the elf/common.h patch
 > goes in?
 > 

Sure,
thanks.

Elena


 > 	* sh-tdep.c (sh_osabi_names): Declare.
 > 	(process_note_abi_tag_sections): New function.
 > 	(get_elfosabi): Ditto.
 > 	(sh_gdbarch_register_os_abi): Ditto.
 > 	(sh_dump_tdep): Ditto.
 > 	_initialize_sh_tdep): Use gdbarch_register to register
 > 	sh_gdbarch_init and sh_dump_tdep.
 > 	* config/sh/tm-sh.h (sh_osabi): Declare.
 > 	(gdbarch_tdep): Add sh_osabi and osabi_name members.
 > 
 > -- 
 >         -- Jason R. Thorpe <thorpej@wasabisystems.com>
 > Index: sh-tdep.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/sh-tdep.c,v
 > retrieving revision 1.52
 > diff -u -r1.52 sh-tdep.c
 > --- sh-tdep.c	12 Apr 2002 18:18:57 -0000	1.52
 > +++ sh-tdep.c	7 May 2002 20:19:36 -0000
 > @@ -41,6 +41,8 @@
 >  #include "regcache.h"
 >  #include "doublest.h"
 >  
 > +#include "elf-bfd.h"
 > +
 >  #include "solib-svr4.h"
 >  
 >  void (*sh_show_regs) (void);
 > @@ -1895,6 +1897,176 @@
 >  }
 >  #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 *
 > @@ -1906,17 +2078,51 @@
 >    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;
 > +
 > +  /* 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;
 > +	}
 > +    }
 >  
 >    /* Find a candidate among the list of pre-declared architectures. */
 > -  arches = gdbarch_list_lookup_by_info (arches, &info);
 > -  if (arches != NULL)
 > -    return arches->gdbarch;
 > +  for (arches = gdbarch_list_lookup_by_info (arches, &info);
 > +       arches != NULL;
 > +       arches = gdbarch_list_lookup_by_info (arches->next, &info))
 > +    {
 > +      /* Make sure the ABI selection matches.  */
 > +      tdep = gdbarch_tdep (arches->gdbarch);
 > +      if (tdep && tdep->sh_osabi == sh_osabi)
 > +	return arches->gdbarch;
 > +    }
 >  
 >    /* None found, create a new architecture from the information
 >       provided. */
 >    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>";
 > +    }
 > +
 >    /* Initialize the register numbers that are not common to all the
 >       variants to -1, if necessary thse will be overwritten in the case
 >       statement below. */
 > @@ -2167,15 +2373,58 @@
 >    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;
 > +
 > +      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]);
 > +        }
 > +    }
 > +
 >    return gdbarch;
 >  }
 >  
 > +static void
 > +sh_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 > +{
 > +  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 > +
 > +  if (tdep == NULL)
 > +    return;
 > +
 > +  if (tdep->osabi_name != NULL)
 > +    fprintf_unfiltered (file, "sh_dump_tdep: 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);
 > +}
 > +
 >  void
 >  _initialize_sh_tdep (void)
 >  {
 >    struct cmd_list_element *c;
 >    
 > -  register_gdbarch_init (bfd_arch_sh, sh_gdbarch_init);
 > +  gdbarch_register (bfd_arch_sh, sh_gdbarch_init, sh_dump_tdep);
 >  
 >    add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 >  }
 > Index: config/sh/tm-sh.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/config/sh/tm-sh.h,v
 > retrieving revision 1.16
 > diff -u -r1.16 tm-sh.h
 > --- config/sh/tm-sh.h	12 Jul 2001 02:29:33 -0000	1.16
 > +++ config/sh/tm-sh.h	7 May 2002 20:19:36 -0000
 > @@ -23,6 +23,17 @@
 >  
 >  #define GDB_MULTI_ARCH 1
 >  
 > +/* 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.  */
 > +};
 > +
 >  /* Information that is dependent on the processor variant. */
 >  
 >  struct gdbarch_tdep
 > @@ -56,6 +67,9 @@
 >      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 */
 >    };
 >  
 >  /* Registers common to all the SH variants. */
 > @@ -81,4 +95,3 @@
 >  #define LITTLE_REMOTE_BREAKPOINT { 0x20, 0xc3 } /* Used in remote.c */
 >  
 >  /*#define NOP   {0x20, 0x0b}*/ /* Who uses this???*/
 > -


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

* Re: [PATCH/RFA] Add OS/ABI infrastructure to SuperH target
  2002-05-07 13:35     ` Elena Zannoni
@ 2002-05-08  7:54       ` Jason R Thorpe
  0 siblings, 0 replies; 6+ messages in thread
From: Jason R Thorpe @ 2002-05-08  7:54 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb-patches

On Tue, May 07, 2002 at 04:35:17PM -0400, Elena Zannoni wrote:

 >  > Anyway, updated patch attached.  OK to commit once the elf/common.h patch
 >  > goes in?
 >  > 
 > 
 > Sure,
 > thanks.

Ok, it's in.  Thanks for the feedback!

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


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

end of thread, other threads:[~2002-05-08 14:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-07  1:45 [PATCH/RFA] Add OS/ABI infrastructure to SuperH target Jason R Thorpe
2002-05-07  8:18 ` Elena Zannoni
2002-05-07  9:29   ` Jason R Thorpe
2002-05-07 13:31   ` Jason R Thorpe
2002-05-07 13:35     ` Elena Zannoni
2002-05-08  7:54       ` 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