* elflink.h (elf_bfd_final_link): Check if dynobj is not NULL
[binutils-gdb.git] / gdb / arch-utils.c
index 3300ce5f8b7ae30d5432ac234371d150272c52e4..175f85eb3d8759ba29339a0ddd4a0a7ee966d63a 100644 (file)
@@ -21,6 +21,7 @@
 #include "defs.h"
 
 #if GDB_MULTI_ARCH
+#include "arch-utils.h"
 #include "gdbcmd.h"
 #include "inferior.h"          /* enum CALL_DUMMY_LOCATION et.al. */
 #else
@@ -38,6 +39,7 @@
 #include "annotate.h"
 #endif
 #include "regcache.h"
+#include "gdb_assert.h"
 
 #include "version.h"
 
@@ -98,6 +100,24 @@ generic_return_value_on_stack_not (struct type *type)
   return 0;
 }
 
+CORE_ADDR
+generic_skip_trampoline_code (CORE_ADDR pc)
+{
+  return 0;
+}
+
+int
+generic_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+  return 0;
+}
+
+int
+generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  return 0;
+}
+
 char *
 legacy_register_name (int i)
 {
@@ -139,6 +159,13 @@ generic_prologue_frameless_p (CORE_ADDR ip)
 #endif
 }
 
+/* New/multi-arched targets should use the correct gdbarch field
+   instead of using this global pointer. */
+int
+legacy_print_insn (bfd_vma vma, disassemble_info *info)
+{
+  return (*tm_print_insn) (vma, info);
+}
 
 /* Helper functions for INNER_THAN */
 
@@ -169,7 +196,7 @@ default_float_format (struct gdbarch *gdbarch)
     {
     case BIG_ENDIAN:
       return &floatformat_ieee_single_big;
-    case LITTLE_ENDIAN:
+    case BFD_ENDIAN_LITTLE:
       return &floatformat_ieee_single_little;
     default:
       internal_error (__FILE__, __LINE__,
@@ -190,7 +217,7 @@ default_double_format (struct gdbarch *gdbarch)
     {
     case BIG_ENDIAN:
       return &floatformat_ieee_double_big;
-    case LITTLE_ENDIAN:
+    case BFD_ENDIAN_LITTLE:
       return &floatformat_ieee_double_little;
     default:
       internal_error (__FILE__, __LINE__,
@@ -214,6 +241,21 @@ generic_register_convertible_not (int num)
 }
   
 
+/* 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;
+}
+
 int
 default_register_sim_regno (int num)
 {
@@ -300,6 +342,61 @@ generic_prepare_to_proceed (int select_it)
   
 }
 
+void
+init_frame_pc_noop (int fromleaf, struct frame_info *prev)
+{
+  return;
+}
+
+void
+init_frame_pc_default (int fromleaf, struct frame_info *prev)
+{
+  if (fromleaf)
+    prev->pc = SAVED_PC_AFTER_CALL (prev->next);
+  else if (prev->next != NULL)
+    prev->pc = FRAME_SAVED_PC (prev->next);
+  else
+    prev->pc = read_pc ();
+}
+
+int
+cannot_register_not (int regnum)
+{
+  return 0;
+}
+
+/* Legacy version of target_virtual_frame_pointer().  Assumes that
+   there is an FP_REGNUM and that it is the same, cooked or raw.  */
+
+void
+legacy_virtual_frame_pointer (CORE_ADDR pc,
+                             int *frame_regnum,
+                             LONGEST *frame_offset)
+{
+  gdb_assert (FP_REGNUM >= 0);
+  *frame_regnum = FP_REGNUM;
+  *frame_offset = 0;
+}
+
+/* Assume the world is flat.  Every register is large enough to fit a
+   target integer.  */
+
+int
+generic_register_raw_size (int regnum)
+{
+  gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS);
+  return TARGET_INT_BIT / HOST_CHAR_BIT;
+}
+
+/* Assume the virtual size corresponds to the virtual type.  */
+
+int
+generic_register_virtual_size (int regnum)
+{
+  return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
+}
+
+\f
 /* Functions to manipulate the endianness of the target.  */
 
 #ifdef TARGET_BYTE_ORDER_SELECTABLE
@@ -370,8 +467,8 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
       if (GDB_MULTI_ARCH)
        {
          struct gdbarch_info info;
-         memset (&info, 0, sizeof info);
-         info.byte_order = LITTLE_ENDIAN;
+         gdbarch_info_init (&info);
+         info.byte_order = BFD_ENDIAN_LITTLE;
          if (! gdbarch_update_p (info))
            {
              printf_unfiltered ("Little endian target not supported by GDB\n");
@@ -379,7 +476,7 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
        }
       else
        {
-         target_byte_order = LITTLE_ENDIAN;
+         target_byte_order = BFD_ENDIAN_LITTLE;
        }
     }
   else if (set_endian_string == endian_big)
@@ -388,7 +485,7 @@ set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
       if (GDB_MULTI_ARCH)
        {
          struct gdbarch_info info;
-         memset (&info, 0, sizeof info);
+         gdbarch_info_init (&info);
          info.byte_order = BIG_ENDIAN;
          if (! gdbarch_update_p (info))
            {
@@ -421,7 +518,7 @@ set_endian_from_file (bfd *abfd)
       if (bfd_big_endian (abfd))
        want = BIG_ENDIAN;
       else
-       want = LITTLE_ENDIAN;
+       want = BFD_ENDIAN_LITTLE;
       if (TARGET_BYTE_ORDER_AUTO)
        target_byte_order = want;
       else if (TARGET_BYTE_ORDER != want)
@@ -567,7 +664,7 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
   else if (GDB_MULTI_ARCH)
     {
       struct gdbarch_info info;
-      memset (&info, 0, sizeof info);
+      gdbarch_info_init (&info);
       info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
       if (info.bfd_arch_info == NULL)
        internal_error (__FILE__, __LINE__,
@@ -599,7 +696,7 @@ set_gdbarch_from_file (bfd *abfd)
   if (GDB_MULTI_ARCH)
     {
       struct gdbarch_info info;
-      memset (&info, 0, sizeof info);
+      gdbarch_info_init (&info);
       info.abfd = abfd;
       if (! gdbarch_update_p (info))
        error ("Architecture of file not recognized.\n");
@@ -636,7 +733,7 @@ initialize_current_architecture (void)
 
   /* determine a default architecture and byte order. */
   struct gdbarch_info info;
-  memset (&info, 0, sizeof (info));
+  gdbarch_info_init (&info);
   
   /* Find a default architecture. */
   if (info.bfd_arch_info == NULL
@@ -665,7 +762,7 @@ initialize_current_architecture (void)
   /* take several guesses at a byte order. */
   /* NB: can't use TARGET_BYTE_ORDER_DEFAULT as its definition is
      forced above. */
-  if (info.byte_order == 0
+  if (info.byte_order == BFD_ENDIAN_UNKNOWN
       && default_bfd_vec != NULL)
     {
       /* Extract BFD's default vector's byte order. */
@@ -675,13 +772,13 @@ initialize_current_architecture (void)
          info.byte_order = BIG_ENDIAN;
          break;
        case BFD_ENDIAN_LITTLE:
-         info.byte_order = LITTLE_ENDIAN;
+         info.byte_order = BFD_ENDIAN_LITTLE;
          break;
        default:
          break;
        }
     }
-  if (info.byte_order == 0)
+  if (info.byte_order == BFD_ENDIAN_UNKNOWN)
     {
       /* look for ``*el-*'' in the target name. */
       const char *chp;
@@ -689,9 +786,9 @@ initialize_current_architecture (void)
       if (chp != NULL
          && chp - 2 >= target_name
          && strncmp (chp - 2, "el", 2) == 0)
-       info.byte_order = LITTLE_ENDIAN;
+       info.byte_order = BFD_ENDIAN_LITTLE;
     }
-  if (info.byte_order == 0)
+  if (info.byte_order == BFD_ENDIAN_UNKNOWN)
     {
       /* Wire it to big-endian!!! */
       info.byte_order = BIG_ENDIAN;
@@ -735,6 +832,19 @@ 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
+   BFD_ENDIAN_BIG is zero.  An explicit initialization function that
+   can explicitly set each field to a well defined value is used.  */
+
+void
+gdbarch_info_init (struct gdbarch_info *info)
+{
+  memset (info, 0, sizeof (struct gdbarch_info));
+  info->byte_order = BFD_ENDIAN_UNKNOWN;
+}
+
 /* */
 
 extern initialize_file_ftype _initialize_gdbarch_utils;