This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch/rfc,rfa:ppc64] Add osabi wildcard support


Hello,

The attached patch adds the ability to specify a wildcard machine when registering an OSABI / arch / machine. It then updates PPC64 GNU/Linux to specify that wild card (-1) instead of zero as the default machine.

Looking at the PPC64 GNU/Linux code:

  gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_LINUX,
                          ppc_linux_init_abi);

I believe that the call is attempting to register ppc_linux_init_abi as the OSABI handler for all arch/machine conbinations. The problem is that machine "0" gets turned into bfd_mach_ppc or bfd_mach_ppc64 dependant on how GDB is built, and they are both incompatible with each other and incompatible . And that in turn restricts the support to just one half of the ISA family making it impossible for GDB to debug both 32 and 64 bit :-(

I know of two ways to fix this. First is the attached patch which modifies osabi.[hc] so that a wildcard machine (-1) can be specified vis:

  gdbarch_register_osabi (bfd_arch_powerpc, -1, GDB_OSABI_LINUX,
                          ppc_linux_init_abi);

and the second is to explicitly register both of these architecture variants vis:

  gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc, ...
  gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc64, ...

(possibly also splitting ppc_linux_init_abi into ppc_linux_init_abi_32 and ppc_linux_init_abi_32).

There are pros and cons to both.

The former will always match, making the code somewhat future proof, the later is far simplier.

preferences?
Andrew

PS: I'm also wondering if the existing ppc arch/machine table is complete. I think it will indicate that e500 is "compatible" with "ppc" when it is not.
2003-10-23  Andrew Cagney  <cagney@redhat.com>

	* ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Pass a -ve wild
	card machine to gdbarch_register_osabi.
	* osabi.c (struct gdb_osabi_handler): Add the filed "arch",
	mention that a NULL arch_info is a wild card.
	(gdbarch_register_osabi): Change type of "machine" to long.  Add a
	-ve machine to the list as a wild card.
	(gdbarch_init_osabi): Check for a wild card.  Use the
	bfd_arch_mach in "info".
	* osabi.h (gdbarch_register_osabi): Add parameter names.  Change
	type of "machine" to long.  Mention that -1 is a machine wild
	card.

Index: doc/ChangeLog
2003-10-23  Andrew Cagney  <cagney@redhat.com>

	* gdbint.texinfo (Target Architecture Definition): Update
	gdbarch_register_osabi removing "gdbarch" parameter and making
	"machine" a long.  Recommend -1 and not zero as a machine.

Index: osabi.c
===================================================================
RCS file: /cvs/src/src/gdb/osabi.c,v
retrieving revision 1.17
diff -u -r1.17 osabi.c
--- osabi.c	24 Aug 2003 11:47:18 -0000	1.17
+++ osabi.c	23 Oct 2003 22:45:04 -0000
@@ -89,10 +89,13 @@
 }
 
 /* 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  
+   one handler for a given OS ABI each architecture family.  When
+   "arch_info" is NULL, indicating a machine wild card, the "arch"
+   should be used.  */
+struct gdb_osabi_handler
 {
   struct gdb_osabi_handler *next;
+  enum bfd_architecture arch;
   const struct bfd_arch_info *arch_info;
   enum gdb_osabi osabi;
   void (*init_osabi)(struct gdbarch_info, struct gdbarch *);
@@ -101,35 +104,42 @@
 static struct gdb_osabi_handler *gdb_osabi_handler_list;
 
 void
-gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
+gdbarch_register_osabi (enum bfd_architecture arch, long machine,
 			enum gdb_osabi osabi,
                         void (*init_osabi)(struct gdbarch_info,
 					   struct gdbarch *))
 {
   struct gdb_osabi_handler **handler_p;
-  const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine);
+  const struct bfd_arch_info *arch_info;
   const char **name_ptr;
 
   /* Registering an OS ABI handler for "unknown" is not allowed.  */
-  if (osabi == GDB_OSABI_UNKNOWN)
+  gdb_assert (osabi != GDB_OSABI_UNKNOWN);
+
+  /* Look up the machine, or use NULL to indicate a wildcard match.  */
+  if (machine >= 0)
     {
-      internal_error
-	(__FILE__, __LINE__,
-	 "gdbarch_register_osabi: An attempt to register a handler for "
-         "OS ABI \"%s\" for architecture %s was made.  The handler will "
-	 "not be registered",
-	 gdbarch_osabi_name (osabi),
-	 bfd_printable_arch_mach (arch, machine));
-      return;
+      /* NOTE: cagney/2003-10-23: The machine 0 returns the
+	 architecture's default machine as specified by the current
+	 target configuration.  For instance, for PPC, the machine 0
+	 returns either bfd_mach_ppc (GDB/BFD configured as
+	 powerpc-*-*) or bfd_mach_ppc64 (GDB/BFD configured as
+	 powerpc64-*-*).  This may not be as you expect.  */
+      arch_info = bfd_lookup_arch (arch, machine);
+      gdb_assert (arch_info != NULL);
     }
+  else
+    arch_info = NULL;
 
-  gdb_assert (arch_info);
-
-  for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL;
+  /* Search the hander list for the first wild-card entry (.arch_info
+     == NULL), or the end of the list.  At the same time, when not
+     adding a wild card, check that the new entry isn't already in the
+     list.  */
+  for (handler_p = &gdb_osabi_handler_list;
+       (*handler_p) != NULL && (*handler_p)->arch_info != NULL;
        handler_p = &(*handler_p)->next)
     {
-      if ((*handler_p)->arch_info == arch_info
-	  && (*handler_p)->osabi == osabi)
+      if (arch_info != NULL && (*handler_p)->arch_info == arch_info)
 	{
 	  internal_error
 	    (__FILE__, __LINE__,
@@ -137,18 +147,31 @@
 	     "has already been registered for architecture %s",
 	     gdbarch_osabi_name (osabi),
 	     arch_info->printable_name);
-	  /* If user wants to continue, override previous definition.  */
-	  (*handler_p)->init_osabi = init_osabi;
-	  return;
 	}
     }
 
-  (*handler_p)
-    = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler));
-  (*handler_p)->next = NULL;
-  (*handler_p)->arch_info = arch_info;
-  (*handler_p)->osabi = osabi;
-  (*handler_p)->init_osabi = init_osabi;
+  /* For wild card entries, walk the rest of the list checking that
+     there isn't a wild card duplicate.  */
+  if (arch_info == NULL)
+    {
+      struct gdb_osabi_handler *p;
+      for (p = (*handler_p); p != NULL; p = p->next)
+	{
+	  gdb_assert (p->arch_info == NULL);
+	  gdb_assert (p->arch != arch);
+	}
+    }
+
+  /* Link the new entry in.  */
+  {
+    struct gdb_osabi_handler *new_handler = XMALLOC (struct gdb_osabi_handler);
+    new_handler->next = (*handler_p);
+    (*handler_p) = new_handler;
+    new_handler->arch_info = arch_info;
+    new_handler->osabi = osabi;
+    new_handler->init_osabi = init_osabi;
+    new_handler->arch = arch;
+  }
 
   /* Add this OS ABI to the list of enum values for "set osabi", if it isn't
      already there.  */
@@ -286,7 +309,6 @@
 void
 gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
   const struct bfd_arch_info *compatible;
   struct gdb_osabi_handler *handler;
 
@@ -303,6 +325,17 @@
       if (handler->osabi != info.osabi)
 	continue;
 
+      /* Wild card match.  */
+      if (handler->arch_info == NULL)
+	{
+	  if (handler->arch == info.bfd_arch_info->arch)
+	    {
+	      handler->init_osabi (info, gdbarch);
+	      return;
+	    }
+	  continue;
+	}
+
       /* Check whether the machine type and architecture of the
          handler are compatible with the desired machine type and
          architecture.
@@ -311,7 +344,8 @@
 	 type that is compatible with the desired machine type.  Right
 	 now we simply return the first match, which is fine for now.
 	 However, we might want to do something smarter in the future.  */
-      compatible = arch_info->compatible (arch_info, handler->arch_info);
+      compatible = info.bfd_arch_info->compatible (info.bfd_arch_info,
+						   handler->arch_info);
       if (compatible == handler->arch_info)
 	{
 	  (*handler->init_osabi) (info, gdbarch);
@@ -319,13 +353,12 @@
 	}
     }
 
-  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 (info.osabi),
-     bfd_printable_arch_mach (arch_info->arch, arch_info->mach));
+  warning ("A handler for the OS ABI \"%s\" is not built into this "
+	   "configuration of GDB, "
+	   "Attempting to continue with the default %s settings\n",
+	   gdbarch_osabi_name (info.osabi),
+	   bfd_printable_arch_mach (info.bfd_arch_info->arch,
+				    info.bfd_arch_info->mach));
 }
 
 
Index: osabi.h
===================================================================
RCS file: /cvs/src/src/gdb/osabi.h,v
retrieving revision 1.8
diff -u -r1.8 osabi.h
--- osabi.h	4 Jan 2003 23:38:45 -0000	1.8
+++ osabi.h	23 Oct 2003 22:45:04 -0000
@@ -32,11 +32,14 @@
 
 /* Register a handler for an OS ABI variant for a given architecture
    and machine type.  There should be only one handler for a given OS
-   ABI for each architecture and machine type combination.  */
-void gdbarch_register_osabi (enum bfd_architecture, unsigned long,
-			     enum gdb_osabi,
-                             void (*)(struct gdbarch_info,
-				      struct gdbarch *));
+   ABI for each architecture and machine type combination.  The
+   machine -1 can be specified as a wild card and will match any
+   machine of the specified architecture (if there is no better
+   match).  */
+void gdbarch_register_osabi (enum bfd_architecture arch, long machine,
+			     enum gdb_osabi osabi,
+                             void (*init_osabi)(struct gdbarch_info,
+						struct gdbarch *));
 
 /* Lookup the OS ABI corresponding to the specified BFD.  */
 enum gdb_osabi gdbarch_lookup_osabi (bfd *);
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.44
diff -u -r1.44 ppc-linux-tdep.c
--- ppc-linux-tdep.c	22 Oct 2003 23:54:11 -0000	1.44
+++ ppc-linux-tdep.c	23 Oct 2003 22:45:05 -0000
@@ -1085,7 +1085,8 @@
 void
 _initialize_ppc_linux_tdep (void)
 {
-  gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_LINUX,
+  /* Accept any machine type, 32-bit or 64-bit.  */
+  gdbarch_register_osabi (bfd_arch_powerpc, -1, GDB_OSABI_LINUX,
 			  ppc_linux_init_abi);
   add_core_fns (&ppc_linux_regset_core_fns);
 }
Index: doc/gdbint.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.177
diff -u -r1.177 gdbint.texinfo
--- doc/gdbint.texinfo	20 Oct 2003 15:38:02 -0000	1.177
+++ doc/gdbint.texinfo	23 Oct 2003 22:45:09 -0000
@@ -2442,12 +2442,11 @@
 Return the name of the OS ABI corresponding to @var{osabi}.
 @end deftypefun
 
-@deftypefun void gdbarch_register_osabi (enum bfd_architecture @var{arch}, unsigned long @var{machine}, enum gdb_osabi @var{osabi}, void (*@var{init_osabi})(struct gdbarch_info @var{info}, struct gdbarch *@var{gdbarch}))
+@deftypefun void gdbarch_register_osabi (enum bfd_architecture @var{arch}, long @var{machine}, enum gdb_osabi @var{osabi}, void (*@var{init_osabi})(struct gdbarch_info @var{info}))
 Register the OS ABI handler specified by @var{init_osabi} for the
 architecture, machine type and OS ABI specified by @var{arch},
-@var{machine} and @var{osabi}.  In most cases, a value of zero for the
-machine type, which implies the architecture's default machine type,
-will suffice.
+@var{machine} and @var{osabi}.  In most cases, a value of -1 for the
+machine type, which implies a wild card match, will suffice.
 @end deftypefun
 
 @deftypefun void gdbarch_register_osabi_sniffer (enum bfd_architecture @var{arch}, enum bfd_flavour @var{flavour}, enum gdb_osabi (*@var{sniffer})(bfd *@var{abfd}))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]