* osabi.c (gdbarch_init_osabi): A handler is okay if it's for an
authorJim Blandy <jimb@codesourcery.com>
Thu, 23 Oct 2003 21:15:50 +0000 (21:15 +0000)
committerJim Blandy <jimb@codesourcery.com>
Thu, 23 Oct 2003 21:15:50 +0000 (21:15 +0000)
architecture the current arch can run code for --- but not if it's
a superset.
(can_run_code_for): New function.

gdb/ChangeLog
gdb/osabi.c

index f6831eadb48b5593e059d6a6b732ebecdf80c494..0c29461ef0aad29e73bf8232b05423c331ba5636 100644 (file)
@@ -1,3 +1,10 @@
+2003-10-23  Jim Blandy  <jimb@redhat.com>
+
+       * osabi.c (gdbarch_init_osabi): A handler is okay if it's for an
+       architecture the current arch can run code for --- but not if it's
+       a superset.
+       (can_run_code_for): New function.
+
 2003-10-22  James E Wilson  <wilson@specifixinc.com>
 
        * MAINTAINERS: Move myself from paper trail section back to write
index dbba578429deb54a035bfa5cb978bdcf3012fae3..e7774b7c3bf2bb47365f83fcfe45999af8cff029 100644 (file)
@@ -283,11 +283,29 @@ gdbarch_lookup_osabi (bfd *abfd)
     return match;
 }
 
+
+/* Return non-zero if architecture A can run code written for
+   architecture B.  */
+static int
+can_run_code_for (const struct bfd_arch_info *a, const struct bfd_arch_info *b)
+{
+  /* BFD's 'A->compatible (A, B)' functions return zero if A and B are
+     incompatible.  But if they are compatible, it returns the 'more
+     featureful' of the two arches.  That is, if A can run code
+     written for B, but B can't run code written for A, then it'll
+     return A.
+
+     struct bfd_arch_info objects are atoms: that is, there's supposed
+     to be exactly one instance for a given machine.  So you can tell
+     whether two are equivalent by comparing pointers.  */
+  return (a == b || a->compatible (a, b) == a);
+}
+
+
 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;
 
   if (info.osabi == GDB_OSABI_UNKNOWN)
@@ -303,16 +321,19 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
       if (handler->osabi != info.osabi)
        continue;
 
-      /* Check whether the machine type and architecture of the
-         handler are compatible with the desired machine type and
-         architecture.
+      /* If the architecture described by ARCH_INFO can run code for
+         the architcture we registered the handler for, then the
+         handler is applicable.  Note, though, that if the handler is
+         for an architecture that is a superset of ARCH_INFO, we can't
+         use that --- it would be perfectly correct for it to install
+         gdbarch methods that refer to registers / instructions /
+         other facilities ARCH_INFO doesn't have.
 
-        NOTE: kettenis/20021027: There may be more than one machine
+         NOTE: kettenis/20021027: There may be more than one machine
         type that is compatible with the desired machine type.  Right
         now we simply return the first match, which is fine for now.
         However, we might want to do something smarter in the future.  */
-      compatible = arch_info->compatible (arch_info, handler->arch_info);
-      if (compatible == handler->arch_info)
+      if (can_run_code_for (arch_info, handler->arch_info))
        {
          (*handler->init_osabi) (info, gdbarch);
          return;