2003-11-20 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / gdbarch.sh
index 7453276f01bd2d43a658e94dca56872dd10ce306..eb015b38d74ac91ba3a917a2e71e4761c0482017 100755 (executable)
@@ -602,7 +602,7 @@ F:2:DEPRECATED_STORE_STRUCT_RETURN:void:deprecated_store_struct_return:CORE_ADDR
 # should take the type/value of the function to be called and not the
 # return type.  This is left as an exercise for the reader.
 
-M:::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, const void *inval, void *outval:valtype, regcache, inval, outval
+M:::enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, void *readbuf, const void *writebuf:valtype, regcache, readbuf, writebuf
 
 # The deprecated methods RETURN_VALUE_ON_STACK, EXTRACT_RETURN_VALUE,
 # STORE_RETURN_VALUE and USE_STRUCT_CONVENTION have all been folded
@@ -704,7 +704,7 @@ f:2:SKIP_TRAMPOLINE_CODE:CORE_ADDR:skip_trampoline_code:CORE_ADDR pc:pc:::generi
 # If IN_SOLIB_DYNSYM_RESOLVE_CODE returns true, and SKIP_SOLIB_RESOLVER
 # evaluates non-zero, this is the address where the debugger will place
 # a step-resume breakpoint to get us past the dynamic linker.
-f:2:SKIP_SOLIB_RESOLVER:CORE_ADDR:skip_solib_resolver:CORE_ADDR pc:pc:::generic_skip_solib_resolver::0
+m:2:SKIP_SOLIB_RESOLVER:CORE_ADDR:skip_solib_resolver:CORE_ADDR pc:pc:::generic_skip_solib_resolver::0
 # For SVR4 shared libraries, each call goes through a small piece of
 # trampoline code in the ".plt" section.  IN_SOLIB_CALL_TRAMPOLINE evaluates
 # to nonzero if we are currently stopped in one of these.
@@ -1161,6 +1161,27 @@ extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size);
 extern int gdbarch_update_p (struct gdbarch_info info);
 
 
+/* Helper function.  Find an architecture matching info.
+
+   INFO should be initialized using gdbarch_info_init, relevant fields
+   set, and then finished using gdbarch_info_fill.
+
+   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.  Set 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_select_hack (struct gdbarch *gdbarch);
+
 
 /* Register per-architecture data-pointer.
 
@@ -1194,6 +1215,7 @@ extern void set_gdbarch_data (struct gdbarch *gdbarch,
 extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
 
 
+
 /* Register per-architecture memory region.
 
    Provide a memory-region swap mechanism.  Per-architecture memory
@@ -1212,33 +1234,6 @@ extern void register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_
 
 
 
-/* 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 */
 
@@ -1250,11 +1245,6 @@ extern void set_gdbarch_from_file (bfd *);
 
 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;
 
@@ -1295,10 +1285,6 @@ cat <<EOF
 /* Static function declarations */
 
 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.  */
 
@@ -1422,24 +1408,11 @@ cat <<EOF
 };
 
 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);
-}
 EOF
 
 # Create a new gdbarch struct
-printf "\n"
-printf "\n"
 cat <<EOF
+
 /* Create a new \`\`struct gdbarch'' based on information provided by
    \`\`struct gdbarch_info''. */
 EOF
@@ -1959,31 +1932,21 @@ register_gdbarch_swap (void *data,
 }
 
 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;
        }
@@ -1992,24 +1955,35 @@ init_gdbarch_swap (struct gdbarch *gdbarch)
     }
 }
 
-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;
 }
 
 
@@ -2132,19 +2106,24 @@ gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
 }
 
 
-/* Update the current architecture. Return ZERO if the update request
-   failed. */
+/* 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.  */
 
-int
-gdbarch_update_p (struct gdbarch_info info)
+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;
 
+  /* The existing architecture has been swapped out - all this code
+     works from a clean slate.  */
+  gdb_assert (current_gdbarch == NULL);
+
   /* Fill in missing parts of the INFO struct using a number of
-     sources: \`\`set ...''; INFOabfd supplied; existing target.  */
-  gdbarch_info_fill (current_gdbarch, &info);
+     sources: "set ..."; INFOabfd supplied; and the existing
+     architecture.  */
+  gdbarch_info_fill (old_gdbarch, &info);
 
   /* Must have found some sort of architecture. */
   gdb_assert (info.bfd_arch_info != NULL);
@@ -2152,28 +2131,28 @@ gdbarch_update_p (struct gdbarch_info info)
   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);
     }
 
-  /* Find the target that knows about this architecture. */
+  /* Find the tdep code that knows about this architecture.  */
   for (rego = gdbarch_registry;
        rego != NULL;
        rego = rego->next)
@@ -2182,86 +2161,61 @@ gdbarch_update_p (struct gdbarch_info info)
   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. */
+  /* Ask the tdep code for an architecture that matches "info".  */
   new_gdbarch = rego->init (info, rego->arches);
 
-  /* Did the target like it?  No. Reject the change and revert to the
-     old architecture.  */
+  /* Did the tdep code like it?  No.  Reject the change and revert to
+     the old architecture.  */
   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).  */
+  /* It's a new architecture.  */
+  if (gdbarch_debug)
+    fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: "
+                       "New architecture 0x%08lx (%s) selected\n",
+                       (long) new_gdbarch,
+                       new_gdbarch->bfd_arch_info->printable_name);
+  
+  /* Insert the 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;
@@ -2269,37 +2223,59 @@ gdbarch_update_p (struct gdbarch_info info)
     rego->arches = this;
   }    
 
-  /* Switch to this new architecture marking it initialized.  */
-  current_gdbarch = new_gdbarch;
-  current_gdbarch->initialized_p = 1;
-  if (gdbarch_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-                         "gdbarch_update: 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;
   verify_gdbarch (new_gdbarch);
+  new_gdbarch->initialized_p = 1;
 
-  /* 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 ();
+  /* Initialize any per-architecture swap areas.  This phase requires
+     a valid global CURRENT_GDBARCH.  Set it momentarially, and then
+     swap the entire architecture out.  */
+  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 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 1;
+  return new_gdbarch;
 }
 
+/* Make the specified architecture current, swapping the existing one
+   out.  */
+
+void
+deprecated_current_gdbarch_select_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 ();
+}
 
 extern void _initialize_gdbarch (void);
 
This page took 0.059138 seconds and 4 git commands to generate.