2004-04-22 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / arch-utils.c
index 5b7a71f478b3fadd7da337bed27540e1018407c9..d76a8e40a7f5051f01b0806dcda4f3fee29b7b1b 100644 (file)
@@ -31,6 +31,8 @@
 #include "gdb_assert.h"
 #include "sim-regno.h"
 
+#include "osabi.h"
+
 #include "version.h"
 
 #include "floatformat.h"
@@ -83,19 +85,19 @@ legacy_register_sim_regno (int regnum)
 }
 
 int
-generic_frameless_function_invocation_not (struct frame_info *fi)
+generic_return_value_on_stack_not (struct type *type)
 {
   return 0;
 }
 
-int
-generic_return_value_on_stack_not (struct type *type)
+CORE_ADDR
+generic_skip_trampoline_code (CORE_ADDR pc)
 {
   return 0;
 }
 
 CORE_ADDR
-generic_skip_trampoline_code (CORE_ADDR pc)
+generic_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   return 0;
 }
@@ -135,12 +137,6 @@ generic_remote_translate_xfer_address (struct gdbarch *gdbarch,
   *rem_len = gdb_len;
 }
 
-int
-generic_prologue_frameless_p (CORE_ADDR ip)
-{
-  return ip == SKIP_PROLOGUE (ip);
-}
-
 /* Helper functions for INNER_THAN */
 
 int
@@ -193,28 +189,6 @@ default_double_format (struct gdbarch *gdbarch)
 
 /* Misc helper functions for targets. */
 
-int
-deprecated_register_convertible_not (int num)
-{
-  return 0;
-}
-  
-
-/* Under some ABI's that specify the `struct convention' for returning
-   structures by value, by the time we've returned from the function,
-   the return value is sitting there in the caller's buffer, but GDB
-   has no way to find the address of that buffer.
-
-   On such architectures, use this function as your
-   extract_struct_value_address method.  When asked to a struct
-   returned by value in this fashion, GDB will print a nice error
-   message, instead of garbage.  */
-CORE_ADDR
-generic_cannot_extract_struct_value_address (char *dummy)
-{
-  return 0;
-}
-
 CORE_ADDR
 core_addr_identity (CORE_ADDR addr)
 {
@@ -324,20 +298,22 @@ generic_register_byte (int regnum)
 int
 legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
-#if !defined (IN_SIGTRAMP)
-  if (SIGTRAMP_START_P ())
-    return (pc) >= SIGTRAMP_START (pc) && (pc) < SIGTRAMP_END (pc);
+#if !defined (DEPRECATED_IN_SIGTRAMP)
+  if (DEPRECATED_SIGTRAMP_START_P ())
+    return ((pc) >= DEPRECATED_SIGTRAMP_START (pc)
+           && (pc) < DEPRECATED_SIGTRAMP_END (pc));
   else
     return name && strcmp ("_sigtramp", name) == 0;
 #else
-  return IN_SIGTRAMP (pc, name);
+  return DEPRECATED_IN_SIGTRAMP (pc, name);
 #endif
 }
 
 int
 legacy_convert_register_p (int regnum, struct type *type)
 {
-  return DEPRECATED_REGISTER_CONVERTIBLE (regnum);
+  return (DEPRECATED_REGISTER_CONVERTIBLE_P ()
+         && DEPRECATED_REGISTER_CONVERTIBLE (regnum));
 }
 
 void
@@ -387,8 +363,17 @@ default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
    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";
@@ -407,7 +392,7 @@ static const char *set_endian_string;
 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
@@ -450,9 +435,18 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
 
 enum set_arch { set_arch_auto, set_arch_manual };
 
-int target_architecture_auto = 1;
+static int target_architecture_auto = 1;
+
+static const char *set_architecture_string;
 
-const char *set_architecture_string;
+const char *
+selected_architecture_name (void)
+{
+  if (target_architecture_auto)
+    return NULL;
+  else
+    return set_architecture_string;
+}
 
 /* Called if the user enters ``show architecture'' without an
    argument. */
@@ -496,17 +490,72 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
   show_architecture (NULL, from_tty);
 }
 
+/* Try to select a global architecture that matches "info".  Return
+   non-zero if the attempt succeds.  */
+int
+gdbarch_update_p (struct gdbarch_info info)
+{
+  struct gdbarch *new_gdbarch = gdbarch_find_by_info (info);
+
+  /* If there no architecture by that name, reject the request.  */
+  if (new_gdbarch == NULL)
+    {
+      if (gdbarch_debug)
+       fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
+                           "Architecture not found\n");
+      return 0;
+    }
+
+  /* If it is the same old architecture, accept the request (but don't
+     swap anything).  */
+  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;
+    }
+
+  /* It's a new architecture, swap it in.  */
+  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_select_hack (new_gdbarch);
+
+  return 1;
+}
+
+/* Return the architecture for ABFD.  If no suitable architecture
+   could be find, return NULL.  */
+
+struct gdbarch *
+gdbarch_from_bfd (bfd *abfd)
+{
+  struct gdbarch *old_gdbarch = current_gdbarch;
+  struct gdbarch *new_gdbarch;
+  struct gdbarch_info info;
+
+  gdbarch_info_init (&info);
+  info.abfd = abfd;
+  return gdbarch_find_by_info (info);
+}
+
 /* Set the dynamic target-system-dependent parameters (architecture,
    byte-order) using information found in the BFD */
 
 void
 set_gdbarch_from_file (bfd *abfd)
 {
-  struct gdbarch_info info;
-  gdbarch_info_init (&info);
-  info.abfd = abfd;
-  if (! gdbarch_update_p (info))
+  struct gdbarch *gdbarch;
+
+  gdbarch = gdbarch_from_bfd (abfd);
+  if (gdbarch == NULL)
     error ("Architecture of file not recognized.\n");
+  deprecated_current_gdbarch_select_hack (gdbarch);
 }
 
 /* Initialize the current architecture.  Update the ``set
@@ -626,7 +675,7 @@ initialize_current_architecture (void)
 
 /* Initialize a gdbarch info to values that will be automatically
    overridden.  Note: Originally, this ``struct info'' was initialized
-   using memset(0).  Unfortunatly, that ran into problems, namely
+   using memset(0).  Unfortunately, that ran into problems, namely
    BFD_ENDIAN_BIG is zero.  An explicit initialization function that
    can explicitly set each field to a well defined value is used.  */
 
@@ -638,6 +687,54 @@ gdbarch_info_init (struct gdbarch_info *info)
   info->osabi = GDB_OSABI_UNINITIALIZED;
 }
 
+/* Similar to init, but this time fill in the blanks.  Information is
+   obtained from the specified architecture, global "set ..." options,
+   and explicitly initialized INFO fields.  */
+
+void
+gdbarch_info_fill (struct gdbarch *gdbarch, struct gdbarch_info *info)
+{
+  /* "(gdb) set architecture ...".  */
+  if (info->bfd_arch_info == NULL
+      && !target_architecture_auto
+      && gdbarch != NULL)
+    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
+      && gdbarch != 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
+      && gdbarch != NULL)
+    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
+      && gdbarch != NULL)
+    info->byte_order = gdbarch_byte_order (gdbarch);
+
+  /* "(gdb) set osabi ...".  Handled by gdbarch_lookup_osabi.  */
+  if (info->osabi == GDB_OSABI_UNINITIALIZED)
+    info->osabi = gdbarch_lookup_osabi (info->abfd);
+  if (info->osabi == GDB_OSABI_UNINITIALIZED
+      && gdbarch != NULL)
+    info->osabi = gdbarch_osabi (gdbarch);
+
+  /* Must have at least filled in the architecture.  */
+  gdb_assert (info->bfd_arch_info != NULL);
+}
+
 /* */
 
 extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */
This page took 0.028789 seconds and 4 git commands to generate.