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]

[wip] gdbarch_find_by_info


Hello,

The attached is a work-in-progress snap adding a new method:

	struct gdbarch *gdbarch_find_by_info()
and
	void deprecated_current_gdbarch_set_hack()

I just tripped over yet another architecture (MIPS) that is struggling with the new architecture swap code. This patch replaces that mechanism with something more robust.

I'm going to merge it in over the comming while

Andrew

PS: Wip? The patch got carried away, need to strip out some unrelated changes
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.102
diff -u -r1.102 arch-utils.c
--- arch-utils.c	9 Nov 2003 12:07:16 -0000	1.102
+++ arch-utils.c	9 Nov 2003 22:36:43 -0000
@@ -30,7 +30,7 @@
 #include "regcache.h"
 #include "gdb_assert.h"
 #include "sim-regno.h"
-
+#include "osabi.h"
 #include "version.h"
 
 #include "floatformat.h"
@@ -378,8 +378,17 @@
    The choice of initial value is entirely arbitrary.  During startup,
    the function initialize_current_architecture() updates this value
    based on default byte-order information extracted from BFD.  */
-int target_byte_order = BFD_ENDIAN_BIG;
-int target_byte_order_auto = 1;
+static int target_byte_order = BFD_ENDIAN_BIG;
+static int target_byte_order_auto = 1;
+
+enum bfd_endian
+selected_byte_order (void)
+{
+  if (target_byte_order_auto)
+    return BFD_ENDIAN_UNKNOWN;
+  else
+    return target_byte_order;
+}
 
 static const char endian_big[] = "big";
 static const char endian_little[] = "little";
@@ -398,7 +407,7 @@
 static void
 show_endian (char *args, int from_tty)
 {
-  if (TARGET_BYTE_ORDER_AUTO)
+  if (target_byte_order_auto)
     printf_unfiltered ("The target endianness is set automatically (currently %s endian)\n",
 		       (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
   else
@@ -445,6 +454,15 @@
 
 const char *set_architecture_string;
 
+const char *
+selected_architecture (void)
+{
+  if (target_architecture_auto)
+    return NULL;
+  else
+    return set_architecture_string;
+}
+
 /* Called if the user enters ``show architecture'' without an
    argument. */
 
@@ -487,31 +505,45 @@
   show_architecture (NULL, from_tty);
 }
 
-/* FIXME: kettenis/20031124: Of the functions that follow, only
-   gdbarch_from_bfd is supposed to survive.  The others will
-   dissappear since in the future GDB will (hopefully) be truly
-   multi-arch.  However, for now we're still stuck with the concept of
-   a single active architecture.  */
+int
+gdbarch_update_p (struct gdbarch_info info)
+{
+  struct gdbarch *new_gdbarch = gdbarch_find_by_info (info);
 
-/* Make GDBARCH the currently selected architecture.  */
+  /* Was the architecture found?  No.  Reject the request.  */
+  if (new_gdbarch == NULL)
+    {
+      if (gdbarch_debug)
+	fprintf_unfiltered (gdb_stdlog, "\
+gdbarch_update_p: Architecture not found\n");
+      return 0;
+    }
 
-static void
-deprecated_select_gdbarch_hack (struct gdbarch *gdbarch)
-{
-  struct gdbarch_info info;
+  /* Old architecture, do nothing.  */
+  if (new_gdbarch == current_gdbarch)
+    {
+      if (gdbarch_debug)
+	fprintf_unfiltered (gdb_stdlog, "\
+gdbarch_update_p: Architecture 0x%08lx (%s) unchanged\n",
+			    (long) new_gdbarch,
+			    gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
+      return 1;
+    }
 
-  /* FIXME: kettenis/20031024: The only way to select a specific
-     architecture is to clone its `struct gdbarch_info', and update
-     according to that copy.  This is gross, but significant work will
-     need to be done before we can take a more sane approach.  */
-  gdbarch_info_init (&info);
-  info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
-  info.byte_order = gdbarch_byte_order (gdbarch);
-  info.osabi = gdbarch_osabi (gdbarch);
-  gdbarch_update_p (info);
-  gdb_assert (gdbarch == current_gdbarch);
+  /* Select this new architecture.  */
+  if (gdbarch_debug)
+    {
+      fprintf_unfiltered (gdb_stdlog, "\
+gdbarch_update_p: New architecture 0x%08lx (%s) selected\n",
+			  (long) new_gdbarch,
+			  gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
+    }
+  deprecated_current_gdbarch_set_hack (new_gdbarch);
+
+  return 1;
 }
 
+
 /* Return the architecture for ABFD.  If no suitable architecture
    could be find, return NULL.  */
 
@@ -522,19 +554,9 @@
   struct gdbarch *new_gdbarch;
   struct gdbarch_info info;
 
-  /* FIXME: kettenis/20031024: The only way to find the architecture
-     for a certain BFD is by doing an architecture update.  This
-     activates the architecture, so we need to reactivate the old
-     architecture.  This is gross, but significant work will need to
-     be done before we can take a more sane approach.  */
   gdbarch_info_init (&info);
   info.abfd = abfd;
-  if (! gdbarch_update_p (info))
-    return NULL;
-
-  new_gdbarch = current_gdbarch;
-  deprecated_select_gdbarch_hack (old_gdbarch);
-  return new_gdbarch;
+  return gdbarch_find_by_info (info);
 }
 
 /* Set the dynamic target-system-dependent parameters (architecture,
@@ -548,7 +570,7 @@
   gdbarch = gdbarch_from_bfd (abfd);
   if (gdbarch == NULL)
     error ("Architecture of file not recognized.\n");
-  deprecated_select_gdbarch_hack (gdbarch);
+  deprecated_current_gdbarch_set_hack (gdbarch);
 }
 
 /* Initialize the current architecture.  Update the ``set
@@ -680,7 +702,44 @@
   info->osabi = GDB_OSABI_UNINITIALIZED;
 }
 
-/* */
+/* Similar, but merge in any existing values found in the specified
+   architecture and/or from globals.  */
+
+void
+gdbarch_info_fill (struct gdbarch *gdbarch, struct gdbarch_info *info)
+{
+  /* ``(gdb) set architecture ...'' */
+  if (info->bfd_arch_info == NULL
+      && !target_architecture_auto)
+    info->bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
+  if (info->bfd_arch_info == NULL
+      && info->abfd != NULL
+      && bfd_get_arch (info->abfd) != bfd_arch_unknown
+      && bfd_get_arch (info->abfd) != bfd_arch_obscure)
+    info->bfd_arch_info = bfd_get_arch_info (info->abfd);
+  if (info->bfd_arch_info == NULL)
+    info->bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
+
+  /* ``(gdb) set byte-order ...'' */
+  if (info->byte_order == BFD_ENDIAN_UNKNOWN
+      && !target_byte_order_auto)
+    info->byte_order = gdbarch_byte_order (gdbarch);
+  /* From the INFO struct. */
+  if (info->byte_order == BFD_ENDIAN_UNKNOWN
+      && info->abfd != NULL)
+    info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG
+		       : bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
+		       : BFD_ENDIAN_UNKNOWN);
+  /* From the current target. */
+  if (info->byte_order == BFD_ENDIAN_UNKNOWN)
+    info->byte_order = gdbarch_byte_order (gdbarch);
+
+  /* ``(gdb) set osabi ...'' is handled by gdbarch_lookup_osabi.  */
+  if (info->osabi == GDB_OSABI_UNINITIALIZED)
+    info->osabi = gdbarch_lookup_osabi (info->abfd);
+  if (info->osabi == GDB_OSABI_UNINITIALIZED)
+    info->osabi = gdbarch_osabi (gdbarch);
+}
 
 extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */
 
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.60
diff -u -r1.60 arch-utils.h
--- arch-utils.h	9 Nov 2003 12:07:16 -0000	1.60
+++ arch-utils.h	9 Nov 2003 22:36:44 -0000
@@ -149,9 +149,21 @@
 
 extern int legacy_register_sim_regno (int regnum);
 
+/* Return the selected byte order, or BFD_ENDIAN_UNKNOWN if no byte
+   order was explicitly selected.  */
+extern enum bfd_endian selected_byte_order (void);
+
+/* Return the selected architecture's name, or NULL if no architecture
+   was explicitly selected.  */
+extern const char *selected_architecture (void);
+
 /* Initialize a ``struct info''.  Can't use memset(0) since some
-   default values are not zero.  */
+   default values are not zero.  "fill" takes all available
+   information and fills in any unspecified fields.  */
+
 extern void gdbarch_info_init (struct gdbarch_info *info);
+extern void gdbarch_info_fill (struct gdbarch *gdbarch,
+			       struct gdbarch_info *info);
 
 /* Return the architecture for ABFD.  If no suitable architecture
    could be find, return NULL.  */
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.256
diff -u -r1.256 gdbarch.c
--- gdbarch.c	9 Nov 2003 12:07:16 -0000	1.256
+++ gdbarch.c	9 Nov 2003 22:37:13 -0000
@@ -54,10 +54,6 @@
 
 static void verify_gdbarch (struct gdbarch *gdbarch);
 static void alloc_gdbarch_data (struct gdbarch *);
-static void init_gdbarch_swap (struct gdbarch *);
-static void clear_gdbarch_swap (struct gdbarch *);
-static void swapout_gdbarch_swap (struct gdbarch *);
-static void swapin_gdbarch_swap (struct gdbarch *);
 
 /* Non-zero if we want to trace architecture code.  */
 
@@ -449,19 +445,6 @@
 
 struct gdbarch *current_gdbarch = &startup_gdbarch;
 
-/* Do any initialization needed for a non-multiarch configuration
-   after the _initialize_MODULE functions have been run.  */
-void
-initialize_non_multiarch (void)
-{
-  alloc_gdbarch_data (&startup_gdbarch);
-  /* Ensure that all swap areas are zeroed so that they again think
-     they are starting from scratch.  */
-  clear_gdbarch_swap (&startup_gdbarch);
-  init_gdbarch_swap (&startup_gdbarch);
-}
-
-
 /* Create a new ``struct gdbarch'' based on information provided by
    ``struct gdbarch_info''. */
 
@@ -603,7 +586,7 @@
 /* Ensure that all values in a GDBARCH are reasonable. */
 
 static void
-verify_gdbarch (struct gdbarch *gdbarch)
+verify_gdbarch (struct gdbarch *current_gdbarch)
 {
   struct ui_file *log;
   struct cleanup *cleanups;
@@ -612,9 +595,9 @@
   log = mem_fileopen ();
   cleanups = make_cleanup_ui_file_delete (log);
   /* fundamental */
-  if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)
+  if (current_gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)
     fprintf_unfiltered (log, "\n\tbyte-order");
-  if (gdbarch->bfd_arch_info == NULL)
+  if (current_gdbarch->bfd_arch_info == NULL)
     fprintf_unfiltered (log, "\n\tbfd_arch_info");
   /* Check those that need to be defined for the given multi-arch level. */
   /* Skip verify of short_bit, invalid_p == 0 */
@@ -625,11 +608,11 @@
   /* Skip verify of double_bit, invalid_p == 0 */
   /* Skip verify of long_double_bit, invalid_p == 0 */
   /* Skip verify of ptr_bit, invalid_p == 0 */
-  if (gdbarch->addr_bit == 0)
-    gdbarch->addr_bit = TARGET_PTR_BIT;
+  if (current_gdbarch->addr_bit == 0)
+    current_gdbarch->addr_bit = TARGET_PTR_BIT;
   /* Skip verify of bfd_vma_bit, invalid_p == 0 */
-  if (gdbarch->char_signed == -1)
-    gdbarch->char_signed = 1;
+  if (current_gdbarch->char_signed == -1)
+    current_gdbarch->char_signed = 1;
   /* Skip verify of read_pc, has predicate */
   /* Skip verify of write_pc, invalid_p == 0 */
   /* Skip verify of read_sp, has predicate */
@@ -637,7 +620,7 @@
   /* Skip verify of pseudo_register_read, has predicate */
   /* Skip verify of pseudo_register_write, has predicate */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->num_regs == -1))
+      && (current_gdbarch->num_regs == -1))
     fprintf_unfiltered (log, "\n\tnum_regs");
   /* Skip verify of num_pseudo_regs, invalid_p == 0 */
   /* Skip verify of sp_regnum, invalid_p == 0 */
@@ -709,27 +692,27 @@
   /* Skip verify of deprecated_frame_init_saved_regs, has predicate */
   /* Skip verify of deprecated_init_extra_frame_info, has predicate */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->skip_prologue == 0))
+      && (current_gdbarch->skip_prologue == 0))
     fprintf_unfiltered (log, "\n\tskip_prologue");
   /* Skip verify of prologue_frameless_p, invalid_p == 0 */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->inner_than == 0))
+      && (current_gdbarch->inner_than == 0))
     fprintf_unfiltered (log, "\n\tinner_than");
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->breakpoint_from_pc == 0))
+      && (current_gdbarch->breakpoint_from_pc == 0))
     fprintf_unfiltered (log, "\n\tbreakpoint_from_pc");
   /* Skip verify of adjust_breakpoint_address, has predicate */
   /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */
   /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->decr_pc_after_break == -1))
+      && (current_gdbarch->decr_pc_after_break == -1))
     fprintf_unfiltered (log, "\n\tdecr_pc_after_break");
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->function_start_offset == -1))
+      && (current_gdbarch->function_start_offset == -1))
     fprintf_unfiltered (log, "\n\tfunction_start_offset");
   /* Skip verify of remote_translate_xfer_address, invalid_p == 0 */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->frame_args_skip == -1))
+      && (current_gdbarch->frame_args_skip == -1))
     fprintf_unfiltered (log, "\n\tframe_args_skip");
   /* Skip verify of frameless_function_invocation, invalid_p == 0 */
   /* Skip verify of deprecated_frame_chain, has predicate */
@@ -745,18 +728,18 @@
   /* Skip verify of frame_align, has predicate */
   /* Skip verify of deprecated_reg_struct_has_addr, has predicate */
   /* Skip verify of stabs_argument_has_addr, invalid_p == 0 */
-  if (gdbarch->float_format == 0)
-    gdbarch->float_format = default_float_format (gdbarch);
-  if (gdbarch->double_format == 0)
-    gdbarch->double_format = default_double_format (gdbarch);
-  if (gdbarch->long_double_format == 0)
-    gdbarch->long_double_format = default_double_format (gdbarch);
+  if (current_gdbarch->float_format == 0)
+    current_gdbarch->float_format = default_float_format (current_gdbarch);
+  if (current_gdbarch->double_format == 0)
+    current_gdbarch->double_format = default_double_format (current_gdbarch);
+  if (current_gdbarch->long_double_format == 0)
+    current_gdbarch->long_double_format = default_double_format (current_gdbarch);
   /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
   /* Skip verify of addr_bits_remove, invalid_p == 0 */
   /* Skip verify of smash_text_address, invalid_p == 0 */
   /* Skip verify of software_single_step, has predicate */
   if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
-      && (gdbarch->print_insn == 0))
+      && (current_gdbarch->print_insn == 0))
     fprintf_unfiltered (log, "\n\tprint_insn");
   /* Skip verify of skip_trampoline_code, invalid_p == 0 */
   /* Skip verify of skip_solib_resolver, invalid_p == 0 */
@@ -5737,31 +5720,21 @@
 }
 
 static void
-clear_gdbarch_swap (struct gdbarch *gdbarch)
-{
-  struct gdbarch_swap *curr;
-  for (curr = gdbarch->swap;
-       curr != NULL;
-       curr = curr->next)
-    {
-      memset (curr->source->data, 0, curr->source->sizeof_data);
-    }
-}
-
-static void
-init_gdbarch_swap (struct gdbarch *gdbarch)
+current_gdbarch_swap_init_hack (void)
 {
   struct gdbarch_swap_registration *rego;
-  struct gdbarch_swap **curr = &gdbarch->swap;
+  struct gdbarch_swap **curr = &current_gdbarch->swap;
   for (rego = gdbarch_swap_registry.registrations;
        rego != NULL;
        rego = rego->next)
     {
       if (rego->data != NULL)
 	{
-	  (*curr) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdbarch_swap);
+	  (*curr) = GDBARCH_OBSTACK_ZALLOC (current_gdbarch,
+					    struct gdbarch_swap);
 	  (*curr)->source = rego;
-	  (*curr)->swap = gdbarch_obstack_zalloc (gdbarch, rego->sizeof_data);
+	  (*curr)->swap = gdbarch_obstack_zalloc (current_gdbarch,
+						  rego->sizeof_data);
 	  (*curr)->next = NULL;
 	  curr = &(*curr)->next;
 	}
@@ -5770,24 +5743,35 @@
     }
 }
 
-static void
-swapout_gdbarch_swap (struct gdbarch *gdbarch)
+static struct gdbarch *
+current_gdbarch_swap_out_hack (void)
 {
+  struct gdbarch *old_gdbarch = current_gdbarch;
   struct gdbarch_swap *curr;
-  for (curr = gdbarch->swap;
+
+  gdb_assert (old_gdbarch != NULL);
+  for (curr = old_gdbarch->swap;
        curr != NULL;
        curr = curr->next)
-    memcpy (curr->swap, curr->source->data, curr->source->sizeof_data);
+    {
+      memcpy (curr->swap, curr->source->data, curr->source->sizeof_data);
+      memset (curr->source->data, 0, curr->source->sizeof_data);
+    }
+  current_gdbarch = NULL;
+  return old_gdbarch;
 }
 
 static void
-swapin_gdbarch_swap (struct gdbarch *gdbarch)
+current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch)
 {
   struct gdbarch_swap *curr;
-  for (curr = gdbarch->swap;
+
+  gdb_assert (current_gdbarch == NULL);
+  for (curr = new_gdbarch->swap;
        curr != NULL;
        curr = curr->next)
     memcpy (curr->source->data, curr->swap, curr->source->sizeof_data);
+  current_gdbarch = new_gdbarch;
 }
 
 
@@ -5910,50 +5894,33 @@
 }
 
 
-/* Update the current architecture. Return ZERO if the update request
-   failed. */
+/* Make the specified architecture current, swapping the existing one
+   out.  */
 
-int
-gdbarch_update_p (struct gdbarch_info info)
+void
+deprecated_current_gdbarch_set_hack (struct gdbarch *new_gdbarch)
+{
+  gdb_assert (new_gdbarch != NULL);
+  gdb_assert (current_gdbarch != NULL);
+  gdb_assert (new_gdbarch->initialized_p);
+  current_gdbarch_swap_out_hack ();
+  current_gdbarch_swap_in_hack (new_gdbarch);
+  architecture_changed_event ();
+}
+
+/* Find an architecture that matches the specified INFO.  Create a new
+   architecture if needed.  Return that new architecture.  Assumes
+   that there is no current architecture.  */
+
+static struct gdbarch *
+find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info)
 {
   struct gdbarch *new_gdbarch;
-  struct gdbarch *old_gdbarch;
   struct gdbarch_registration *rego;
 
   /* Fill in missing parts of the INFO struct using a number of
      sources: ``set ...''; INFOabfd supplied; existing target.  */
-
-  /* ``(gdb) set architecture ...'' */
-  if (info.bfd_arch_info == NULL
-      && !TARGET_ARCHITECTURE_AUTO)
-    info.bfd_arch_info = TARGET_ARCHITECTURE;
-  if (info.bfd_arch_info == NULL
-      && info.abfd != NULL
-      && bfd_get_arch (info.abfd) != bfd_arch_unknown
-      && bfd_get_arch (info.abfd) != bfd_arch_obscure)
-    info.bfd_arch_info = bfd_get_arch_info (info.abfd);
-  if (info.bfd_arch_info == NULL)
-    info.bfd_arch_info = TARGET_ARCHITECTURE;
-
-  /* ``(gdb) set byte-order ...'' */
-  if (info.byte_order == BFD_ENDIAN_UNKNOWN
-      && !TARGET_BYTE_ORDER_AUTO)
-    info.byte_order = TARGET_BYTE_ORDER;
-  /* From the INFO struct. */
-  if (info.byte_order == BFD_ENDIAN_UNKNOWN
-      && info.abfd != NULL)
-    info.byte_order = (bfd_big_endian (info.abfd) ? BFD_ENDIAN_BIG
-		       : bfd_little_endian (info.abfd) ? BFD_ENDIAN_LITTLE
-		       : BFD_ENDIAN_UNKNOWN);
-  /* From the current target. */
-  if (info.byte_order == BFD_ENDIAN_UNKNOWN)
-    info.byte_order = TARGET_BYTE_ORDER;
-
-  /* ``(gdb) set osabi ...'' is handled by gdbarch_lookup_osabi.  */
-  if (info.osabi == GDB_OSABI_UNINITIALIZED)
-    info.osabi = gdbarch_lookup_osabi (info.abfd);
-  if (info.osabi == GDB_OSABI_UNINITIALIZED)
-    info.osabi = current_gdbarch->osabi;
+  gdbarch_info_fill (old_gdbarch, &info);
 
   /* Must have found some sort of architecture. */
   gdb_assert (info.bfd_arch_info != NULL);
@@ -5961,24 +5928,24 @@
   if (gdbarch_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
-			  "gdbarch_update: info.bfd_arch_info %s\n",
+			  "find_arch_by_info: info.bfd_arch_info %s\n",
 			  (info.bfd_arch_info != NULL
 			   ? info.bfd_arch_info->printable_name
 			   : "(null)"));
       fprintf_unfiltered (gdb_stdlog,
-			  "gdbarch_update: info.byte_order %d (%s)\n",
+			  "find_arch_by_info: info.byte_order %d (%s)\n",
 			  info.byte_order,
 			  (info.byte_order == BFD_ENDIAN_BIG ? "big"
 			   : info.byte_order == BFD_ENDIAN_LITTLE ? "little"
 			   : "default"));
       fprintf_unfiltered (gdb_stdlog,
-			  "gdbarch_update: info.osabi %d (%s)\n",
+			  "find_arch_by_info: info.osabi %d (%s)\n",
 			  info.osabi, gdbarch_osabi_name (info.osabi));
       fprintf_unfiltered (gdb_stdlog,
-			  "gdbarch_update: info.abfd 0x%lx\n",
+			  "find_arch_by_info: info.abfd 0x%lx\n",
 			  (long) info.abfd);
       fprintf_unfiltered (gdb_stdlog,
-			  "gdbarch_update: info.tdep_info 0x%lx\n",
+			  "find_arch_by_info: info.tdep_info 0x%lx\n",
 			  (long) info.tdep_info);
     }
 
@@ -5991,25 +5958,10 @@
   if (rego == NULL)
     {
       if (gdbarch_debug)
-	fprintf_unfiltered (gdb_stdlog, "gdbarch_update: No matching architecture\n");
+	fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: No matching architecture\n");
       return 0;
     }
 
-  /* Swap the data belonging to the old target out setting the
-     installed data to zero.  This stops the ->init() function trying
-     to refer to the previous architecture's global data structures.  */
-  swapout_gdbarch_swap (current_gdbarch);
-  clear_gdbarch_swap (current_gdbarch);
-
-  /* Save the previously selected architecture, setting the global to
-     NULL.  This stops ->init() trying to use the previous
-     architecture's configuration.  The previous architecture may not
-     even be of the same architecture family.  The most recent
-     architecture of the same family is found at the head of the
-     rego->arches list.  */
-  old_gdbarch = current_gdbarch;
-  current_gdbarch = NULL;
-
   /* Ask the target for a replacement architecture. */
   new_gdbarch = rego->init (info, rego->arches);
 
@@ -6018,97 +5970,93 @@
   if (new_gdbarch == NULL)
     {
       if (gdbarch_debug)
-	fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\n");
-      swapin_gdbarch_swap (old_gdbarch);
-      current_gdbarch = old_gdbarch;
-      return 0;
+	fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: Target rejected architecture\n");
+      return NULL;
     }
 
-  /* Did the architecture change?  No.  Oops, put the old architecture
-     back.  */
-  if (old_gdbarch == new_gdbarch)
+  /* Is this a pre-existing architecture (as determined by already
+     being initialized)?  Move it to the front of the architecture
+     list (keeping the list sorted Most Recently Used).  */
+  if (new_gdbarch->initialized_p)
     {
+      struct gdbarch_list **list;
+      struct gdbarch_list *this;
       if (gdbarch_debug)
-	fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\n",
+	fprintf_unfiltered (gdb_stdlog,
+			    "find_arch_by_info: Previous architecture 0x%08lx (%s) selected\n",
 			    (long) new_gdbarch,
 			    new_gdbarch->bfd_arch_info->printable_name);
-      swapin_gdbarch_swap (old_gdbarch);
-      current_gdbarch = old_gdbarch;
-      return 1;
+      /* Find the existing arch in the list.  */
+      for (list = &rego->arches;
+	   (*list) != NULL && (*list)->gdbarch != new_gdbarch;
+	   list = &(*list)->next);
+      /* It had better be in the list of architectures.  */
+      gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch);
+      /* Unlink THIS.  */
+      this = (*list);
+      (*list) = this->next;
+      /* Insert THIS at the front.  */
+      this->next = rego->arches;
+      rego->arches = this;
+      /* Return it.  */
+      return new_gdbarch;
     }
 
-  /* Is this a pre-existing architecture?  Yes. Move it to the front
-     of the list of architectures (keeping the list sorted Most
-     Recently Used) and then copy it in.  */
-  {
-    struct gdbarch_list **list;
-    for (list = &rego->arches;
-	 (*list) != NULL;
-	 list = &(*list)->next)
-      {
-	if ((*list)->gdbarch == new_gdbarch)
-	  {
-	    struct gdbarch_list *this;
-	    if (gdbarch_debug)
-	      fprintf_unfiltered (gdb_stdlog,
-				  "gdbarch_update: Previous architecture 0x%08lx (%s) selected\n",
-				  (long) new_gdbarch,
-				  new_gdbarch->bfd_arch_info->printable_name);
-	    /* Unlink this.  */
-	    this = (*list);
-	    (*list) = this->next;
-	    /* Insert in the front.  */
-	    this->next = rego->arches;
-	    rego->arches = this;
-	    /* Copy the new architecture in.  */
-	    current_gdbarch = new_gdbarch;
-	    swapin_gdbarch_swap (new_gdbarch);
-	    architecture_changed_event ();
-	    return 1;
-	  }
-      }
-  }
-
-  /* Prepend this new architecture to the architecture list (keep the
-     list sorted Most Recently Used).  */
-  {
-    struct gdbarch_list *this = XMALLOC (struct gdbarch_list);
-    this->next = rego->arches;
-    this->gdbarch = new_gdbarch;
-    rego->arches = this;
-  }    
-
-  /* Switch to this new architecture marking it initialized.  */
-  current_gdbarch = new_gdbarch;
-  current_gdbarch->initialized_p = 1;
+  /* It's a new architecture.  */
   if (gdbarch_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
-			  "gdbarch_update: New architecture 0x%08lx (%s) selected\n",
+			  "find_arch_by_info: New architecture 0x%08lx (%s) selected\n",
 			  (long) new_gdbarch,
 			  new_gdbarch->bfd_arch_info->printable_name);
     }
   
-  /* Check that the newly installed architecture is valid.  Plug in
-     any post init values.  */
-  new_gdbarch->dump_tdep = rego->dump_tdep;
+  /* Insert new architecture into the front of the architecture list
+     (keep the list sorted Most Recently Used).  */
+  {
+    struct gdbarch_list *this = XMALLOC (struct gdbarch_list);
+    this->next = rego->arches;
+    this->gdbarch = new_gdbarch;
+    rego->arches = this;
+  }    
+
+  /* Validate the new architecture.  */
   verify_gdbarch (new_gdbarch);
 
   /* Initialize the per-architecture memory (swap) areas.
-     CURRENT_GDBARCH must be update before these modules are
-     called. */
-  init_gdbarch_swap (new_gdbarch);
-  
-  /* Initialize the per-architecture data.  CURRENT_GDBARCH
-     must be updated before these modules are called. */
-  architecture_changed_event ();
-
+     CURRENT_GDBARCH must be update before these modules are called.
+     Swap the new architecture out.  */
+  new_gdbarch->initialized_p = 1;
+  new_gdbarch->dump_tdep = rego->dump_tdep;
+  current_gdbarch = new_gdbarch;
+  current_gdbarch_swap_init_hack ();
+  current_gdbarch_swap_out_hack ();
   if (gdbarch_debug)
-    gdbarch_dump (current_gdbarch, gdb_stdlog);
+    gdbarch_dump (new_gdbarch, gdb_stdlog);
 
-  return 1;
+  return new_gdbarch;
 }
 
+struct gdbarch *
+gdbarch_find_by_info (struct gdbarch_info info)
+{
+  /* Save the previously selected architecture, setting the global to
+     NULL.  This stops things like gdbarch->init() trying to use the
+     previous architecture's configuration.  The previous architecture
+     may not even be of the same architecture family.  The most recent
+     architecture of the same family is found at the head of the
+     rego->arches list.  */
+  struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
+
+  /* Find the specified architecture.  */
+  struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
+
+  /* Restore the existing architecture.  */
+  gdb_assert (current_gdbarch == NULL);
+  current_gdbarch_swap_in_hack (old_gdbarch);
+
+  return new_gdbarch;
+}
 
 extern void _initialize_gdbarch (void);
 
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.224
diff -u -r1.224 gdbarch.h
--- gdbarch.h	9 Nov 2003 12:07:16 -0000	1.224
+++ gdbarch.h	9 Nov 2003 22:37:28 -0000
@@ -2556,6 +2556,29 @@
 
 
 
+/* Helper function.  Find an architecture matching info.   info.
+
+   INFO should be initialized using gdbarch_info_init, and then all
+   relevant fields modified.
+
+   Returns the corresponding architecture, or NULL if no matching
+   architecture was found.  "current_gdbarch" is not updated.  */
+
+extern struct gdbarch *gdbarch_find_by_info (struct gdbarch_info info);
+
+
+/* Helper function.  Switch the global "current_gdbarch" to GDBARCH.
+
+   FIXME: kettenis/20031124: Of the functions that follow, only
+   gdbarch_from_bfd is supposed to survive.  The others will
+   dissappear since in the future GDB will (hopefully) be truly
+   multi-arch.  However, for now we're still stuck with the concept of
+   a single active architecture.  */
+
+extern void deprecated_current_gdbarch_set_hack (struct gdbarch *gdbarch);
+
+
+
 /* Register per-architecture data-pointer.
 
    Reserve space for a per-architecture data-pointer.  An identifier
@@ -2588,6 +2611,7 @@
 extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
 
 
+
 /* Register per-architecture memory region.
 
    Provide a memory-region swap mechanism.  Per-architecture memory
@@ -2606,33 +2630,6 @@
 
 
 
-/* The target-system-dependent byte order is dynamic */
-
-extern int target_byte_order;
-#ifndef TARGET_BYTE_ORDER
-#define TARGET_BYTE_ORDER (target_byte_order + 0)
-#endif
-
-extern int target_byte_order_auto;
-#ifndef TARGET_BYTE_ORDER_AUTO
-#define TARGET_BYTE_ORDER_AUTO (target_byte_order_auto + 0)
-#endif
-
-
-
-/* The target-system-dependent BFD architecture is dynamic */
-
-extern int target_architecture_auto;
-#ifndef TARGET_ARCHITECTURE_AUTO
-#define TARGET_ARCHITECTURE_AUTO (target_architecture_auto + 0)
-#endif
-
-extern const struct bfd_arch_info *target_architecture;
-#ifndef TARGET_ARCHITECTURE
-#define TARGET_ARCHITECTURE (target_architecture + 0)
-#endif
-
-
 /* Set the dynamic target-system-dependent parameters (architecture,
    byte-order, ...) using information found in the BFD */
 
@@ -2643,11 +2640,6 @@
    our list.  */
 
 extern void initialize_current_architecture (void);
-
-/* For non-multiarched targets, do any initialization of the default
-   gdbarch object necessary after the _initialize_MODULE functions
-   have run.  */
-extern void initialize_non_multiarch (void);
 
 /* gdbarch trace variable */
 extern int gdbarch_debug;
Index: remote-sim.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sim.c,v
retrieving revision 1.32
diff -u -r1.32 remote-sim.c
--- remote-sim.c	2 Oct 2003 20:28:30 -0000	1.32
+++ remote-sim.c	9 Nov 2003 22:37:36 -0000
@@ -42,6 +42,7 @@
 #include "regcache.h"
 #include "gdb_assert.h"
 #include "sim-regno.h"
+#include "arch-utils.h"
 
 /* Prototypes */
 
@@ -504,27 +505,23 @@
   strcpy (arg_buf, "gdbsim");	/* 7 */
   /* Specify the byte order for the target when it is both selectable
      and explicitly specified by the user (not auto detected). */
-  if (!TARGET_BYTE_ORDER_AUTO)
+  switch (selected_byte_order ())
     {
-      switch (TARGET_BYTE_ORDER)
-	{
-	case BFD_ENDIAN_BIG:
-	  strcat (arg_buf, " -E big");
-	  break;
-	case BFD_ENDIAN_LITTLE:
-	  strcat (arg_buf, " -E little");
-	  break;
-	default:
-	  internal_error (__FILE__, __LINE__,
-			  "Value of TARGET_BYTE_ORDER unknown");
-	}
+    case BFD_ENDIAN_BIG:
+      strcat (arg_buf, " -E big");
+      break;
+    case BFD_ENDIAN_LITTLE:
+      strcat (arg_buf, " -E little");
+      break;
+    case BFD_ENDIAN_UNKNOWN:
+      break;
     }
   /* Specify the architecture of the target when it has been
      explicitly specified */
-  if (!TARGET_ARCHITECTURE_AUTO)
+  if (selected_architecture () != NULL)
     {
       strcat (arg_buf, " --architecture=");
-      strcat (arg_buf, TARGET_ARCHITECTURE->printable_name);
+      strcat (arg_buf, selected_architecture ());
     }
   /* finally, any explicit args */
   if (args)

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