2002-11-13 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / sparc-tdep.c
index 4f7f57b0d37b40c3e5a49455ed967d1148767799..21e40be44907ed702b1d5382404acc5af280e2d1 100644 (file)
 #include "arch-utils.h"
 #include "frame.h"
 #include "inferior.h"
-#include "obstack.h"
 #include "target.h"
 #include "value.h"
 #include "bfd.h"
 #include "gdb_string.h"
 #include "regcache.h"
+#include "osabi.h"
 
 #ifdef USE_PROC_FS
 #include <sys/procfs.h>
@@ -111,6 +111,8 @@ struct gdbarch_tdep
     int reg_save_offset;
     int call_dummy_call_offset;
     int print_insn_mach;
+
+    enum gdb_osabi osabi;
   };
 
 /* Now make GDB_TARGET_IS_SPARC64 a runtime test.  */
@@ -313,7 +315,7 @@ sparc_init_extra_frame_info (int fromleaf, struct frame_info *fi)
          it later.  */
       if (fi->next->next != NULL
          && (fi->next->next->signal_handler_caller
-             || frame_in_dummy (fi->next->next))
+             || deprecated_frame_in_dummy (fi->next->next))
          && frameless_look_for_prologue (fi->next))
        {
          /* A frameless function interrupted by a signal did not change
@@ -486,7 +488,7 @@ sparc_frame_saved_pc (struct frame_info *frame)
   else if (frame->extra_info->in_prologue ||
           (frame->next != NULL &&
            (frame->next->signal_handler_caller ||
-            frame_in_dummy (frame->next)) &&
+            deprecated_frame_in_dummy (frame->next)) &&
            frameless_look_for_prologue (frame)))
     {
       /* A frameless function interrupted by a signal did not save
@@ -855,10 +857,20 @@ sparc_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
            addr = frame1->frame + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE
              - (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE);
          else if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8)
+           /* NOTE: cagney/2002-05-04: The call to get_prev_frame()
+               is safe/cheap - there will always be a prev frame.
+               This is because frame1 is initialized to frame->next
+               (frame1->prev == frame) and is then advanced towards
+               the innermost (next) frame.  */
            addr = (get_prev_frame (frame1)->extra_info->bottom
                    + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
                    + FRAME_SAVED_I0);
          else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8)
+           /* NOTE: cagney/2002-05-04: The call to get_prev_frame()
+               is safe/cheap - there will always be a prev frame.
+               This is because frame1 is initialized to frame->next
+               (frame1->prev == frame) and is then advanced towards
+               the innermost (next) frame.  */
            addr = (get_prev_frame (frame1)->extra_info->bottom
                    + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
                    + FRAME_SAVED_L0);
@@ -944,7 +956,7 @@ sparc_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
        *lval = lval_register;
       addr = REGISTER_BYTE (regnum);
       if (raw_buffer != NULL)
-       read_register_gen (regnum, raw_buffer);
+       deprecated_read_register_gen (regnum, raw_buffer);
     }
   if (addrp != NULL)
     *addrp = addr;
@@ -978,32 +990,34 @@ sparc_push_dummy_frame (void)
   if (GDB_TARGET_IS_SPARC64)
     {
       /* PC, NPC, CCR, FSR, FPRS, Y, ASI */
-      read_register_bytes (REGISTER_BYTE (PC_REGNUM), &register_temp[0],
-                          REGISTER_RAW_SIZE (PC_REGNUM) * 7);
-      read_register_bytes (REGISTER_BYTE (PSTATE_REGNUM), 
-                          &register_temp[7 * SPARC_INTREG_SIZE],
-                          REGISTER_RAW_SIZE (PSTATE_REGNUM));
+      deprecated_read_register_bytes (REGISTER_BYTE (PC_REGNUM),
+                                     &register_temp[0],
+                                     REGISTER_RAW_SIZE (PC_REGNUM) * 7);
+      deprecated_read_register_bytes (REGISTER_BYTE (PSTATE_REGNUM), 
+                                     &register_temp[7 * SPARC_INTREG_SIZE],
+                                     REGISTER_RAW_SIZE (PSTATE_REGNUM));
       /* FIXME: not sure what needs to be saved here.  */
     }
   else
     {
       /* Y, PS, WIM, TBR, PC, NPC, FPS, CPS regs */
-      read_register_bytes (REGISTER_BYTE (Y_REGNUM), &register_temp[0],
-                          REGISTER_RAW_SIZE (Y_REGNUM) * 8);
+      deprecated_read_register_bytes (REGISTER_BYTE (Y_REGNUM),
+                                     &register_temp[0],
+                                     REGISTER_RAW_SIZE (Y_REGNUM) * 8);
     }
 
-  read_register_bytes (REGISTER_BYTE (O0_REGNUM),
-                      &register_temp[8 * SPARC_INTREG_SIZE],
-                      SPARC_INTREG_SIZE * 8);
+  deprecated_read_register_bytes (REGISTER_BYTE (O0_REGNUM),
+                                 &register_temp[8 * SPARC_INTREG_SIZE],
+                                 SPARC_INTREG_SIZE * 8);
 
-  read_register_bytes (REGISTER_BYTE (G0_REGNUM),
-                      &register_temp[16 * SPARC_INTREG_SIZE],
-                      SPARC_INTREG_SIZE * 8);
+  deprecated_read_register_bytes (REGISTER_BYTE (G0_REGNUM),
+                                 &register_temp[16 * SPARC_INTREG_SIZE],
+                                 SPARC_INTREG_SIZE * 8);
 
   if (SPARC_HAS_FPU)
-    read_register_bytes (REGISTER_BYTE (FP0_REGNUM),
-                        &register_temp[24 * SPARC_INTREG_SIZE],
-                        FP_REGISTER_BYTES);
+    deprecated_read_register_bytes (REGISTER_BYTE (FP0_REGNUM),
+                                   &register_temp[24 * SPARC_INTREG_SIZE],
+                                   FP_REGISTER_BYTES);
 
   sp -= DUMMY_STACK_SIZE;
 
@@ -1225,28 +1239,28 @@ sparc_pop_frame (void)
       if (fsr[FP0_REGNUM])
        {
          read_memory (fsr[FP0_REGNUM], raw_buffer, FP_REGISTER_BYTES);
-         write_register_bytes (REGISTER_BYTE (FP0_REGNUM),
-                               raw_buffer, FP_REGISTER_BYTES);
+         deprecated_write_register_bytes (REGISTER_BYTE (FP0_REGNUM),
+                                          raw_buffer, FP_REGISTER_BYTES);
        }
       if (!(GDB_TARGET_IS_SPARC64))
        {
          if (fsr[FPS_REGNUM])
            {
              read_memory (fsr[FPS_REGNUM], raw_buffer, SPARC_INTREG_SIZE);
-             write_register_gen (FPS_REGNUM, raw_buffer);
+             deprecated_write_register_gen (FPS_REGNUM, raw_buffer);
            }
          if (fsr[CPS_REGNUM])
            {
              read_memory (fsr[CPS_REGNUM], raw_buffer, SPARC_INTREG_SIZE);
-             write_register_gen (CPS_REGNUM, raw_buffer);
+             deprecated_write_register_gen (CPS_REGNUM, raw_buffer);
            }
        }
     }
   if (fsr[G1_REGNUM])
     {
       read_memory (fsr[G1_REGNUM], raw_buffer, 7 * SPARC_INTREG_SIZE);
-      write_register_bytes (REGISTER_BYTE (G1_REGNUM), raw_buffer,
-                           7 * SPARC_INTREG_SIZE);
+      deprecated_write_register_bytes (REGISTER_BYTE (G1_REGNUM), raw_buffer,
+                                      7 * SPARC_INTREG_SIZE);
     }
 
   if (frame->extra_info->flat)
@@ -1298,11 +1312,11 @@ sparc_pop_frame (void)
 
       /* Restore the out registers.
          Among other things this writes the new stack pointer.  */
-      write_register_bytes (REGISTER_BYTE (O0_REGNUM), raw_buffer,
-                           SPARC_INTREG_SIZE * 8);
+      deprecated_write_register_bytes (REGISTER_BYTE (O0_REGNUM), raw_buffer,
+                                      SPARC_INTREG_SIZE * 8);
 
-      write_register_bytes (REGISTER_BYTE (L0_REGNUM), reg_temp,
-                           SPARC_INTREG_SIZE * 16);
+      deprecated_write_register_bytes (REGISTER_BYTE (L0_REGNUM), reg_temp,
+                                      SPARC_INTREG_SIZE * 16);
     }
 
   if (!(GDB_TARGET_IS_SPARC64))
@@ -1597,37 +1611,37 @@ fill_gregset (gdb_gregset_t *gregsetp, int regno)
 
   for (regi = 0; regi <= R_I7; regi++)
     if ((regno == -1) || (regno == regi))
-      read_register_gen (regi, (char *) (regp + regi) + offset);
+      deprecated_read_register_gen (regi, (char *) (regp + regi) + offset);
 
   if ((regno == -1) || (regno == PC_REGNUM))
-    read_register_gen (PC_REGNUM, (char *) (regp + R_PC) + offset);
+    deprecated_read_register_gen (PC_REGNUM, (char *) (regp + R_PC) + offset);
 
   if ((regno == -1) || (regno == NPC_REGNUM))
-    read_register_gen (NPC_REGNUM, (char *) (regp + R_nPC) + offset);
+    deprecated_read_register_gen (NPC_REGNUM, (char *) (regp + R_nPC) + offset);
 
   if ((regno == -1) || (regno == Y_REGNUM))
-    read_register_gen (Y_REGNUM, (char *) (regp + R_Y) + offset);
+    deprecated_read_register_gen (Y_REGNUM, (char *) (regp + R_Y) + offset);
 
   if (GDB_TARGET_IS_SPARC64)
     {
 #ifdef R_CCR
       if (regno == -1 || regno == CCR_REGNUM)
-       read_register_gen (CCR_REGNUM, ((char *) (regp + R_CCR)) + offset);
+       deprecated_read_register_gen (CCR_REGNUM, ((char *) (regp + R_CCR)) + offset);
 #endif
 #ifdef R_FPRS
       if (regno == -1 || regno == FPRS_REGNUM)
-       read_register_gen (FPRS_REGNUM, ((char *) (regp + R_FPRS)) + offset);
+       deprecated_read_register_gen (FPRS_REGNUM, ((char *) (regp + R_FPRS)) + offset);
 #endif
 #ifdef R_ASI
       if (regno == -1 || regno == ASI_REGNUM)
-       read_register_gen (ASI_REGNUM, ((char *) (regp + R_ASI)) + offset);
+       deprecated_read_register_gen (ASI_REGNUM, ((char *) (regp + R_ASI)) + offset);
 #endif
     }
   else /* sparc32 */
     {
 #ifdef R_PS
       if (regno == -1 || regno == PS_REGNUM)
-       read_register_gen (PS_REGNUM, ((char *) (regp + R_PS)) + offset);
+       deprecated_read_register_gen (PS_REGNUM, ((char *) (regp + R_PS)) + offset);
 #endif
 
       /* For 64-bit hosts, R_WIM and R_TBR may not be defined.
@@ -1643,18 +1657,18 @@ fill_gregset (gdb_gregset_t *gregsetp, int regno)
 
 #if defined (R_WIM)
       if (regno == -1 || regno == WIM_REGNUM)
-       read_register_gen (WIM_REGNUM, ((char *) (regp + R_WIM)) + offset);
+       deprecated_read_register_gen (WIM_REGNUM, ((char *) (regp + R_WIM)) + offset);
 #else
       if (regno == -1 || regno == WIM_REGNUM)
-       read_register_gen (WIM_REGNUM, NULL);
+       deprecated_read_register_gen (WIM_REGNUM, NULL);
 #endif
 
 #if defined (R_TBR)
       if (regno == -1 || regno == TBR_REGNUM)
-       read_register_gen (TBR_REGNUM, ((char *) (regp + R_TBR)) + offset);
+       deprecated_read_register_gen (TBR_REGNUM, ((char *) (regp + R_TBR)) + offset);
 #else
       if (regno == -1 || regno == TBR_REGNUM)
-       read_register_gen (TBR_REGNUM, NULL);
+       deprecated_read_register_gen (TBR_REGNUM, NULL);
 #endif
     }
 }
@@ -1846,7 +1860,7 @@ decode_asi (int val)
    Pretty print various registers.  */
 /* FIXME: Would be nice if this did some fancy things for 32 bit sparc.  */
 
-void
+static void
 sparc_print_register_hook (int regno)
 {
   ULONGEST val;
@@ -2016,6 +2030,146 @@ sparc_print_register_hook (int regno)
 
 #undef BITS
 }
+
+static void
+sparc_print_registers (struct gdbarch *gdbarch,
+                      struct ui_file *file,
+                      struct frame_info *frame,
+                      int regnum, int print_all,
+                      void (*print_register_hook) (int))
+{
+  int i;
+  const int numregs = NUM_REGS + NUM_PSEUDO_REGS;
+  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+  char *virtual_buffer = alloca (MAX_REGISTER_VIRTUAL_SIZE);
+
+  for (i = 0; i < numregs; i++)
+    {
+      /* Decide between printing all regs, non-float / vector regs, or
+         specific reg.  */
+      if (regnum == -1)
+       {
+         if (!print_all)
+           {
+             if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+               continue;
+             if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (i)))
+               continue;
+           }
+       }
+      else
+       {
+         if (i != regnum)
+           continue;
+       }
+
+      /* If the register name is empty, it is undefined for this
+         processor, so don't display anything.  */
+      if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0')
+       continue;
+
+      fputs_filtered (REGISTER_NAME (i), file);
+      print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), file);
+
+      /* Get the data in raw format.  */
+      if (! frame_register_read (frame, i, raw_buffer))
+       {
+         fprintf_filtered (file, "*value not available*\n");
+         continue;
+       }
+
+      /* FIXME: cagney/2002-08-03: This code shouldn't be necessary.
+         The function frame_register_read() should have returned the
+         pre-cooked register so no conversion is necessary.  */
+      /* Convert raw data to virtual format if necessary.  */
+      if (REGISTER_CONVERTIBLE (i))
+       {
+         REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+                                      raw_buffer, virtual_buffer);
+       }
+      else
+       {
+         memcpy (virtual_buffer, raw_buffer,
+                 REGISTER_VIRTUAL_SIZE (i));
+       }
+
+      /* If virtual format is floating, print it that way, and in raw
+         hex.  */
+      if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+       {
+         int j;
+
+         val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+                    file, 0, 1, 0, Val_pretty_default);
+
+         fprintf_filtered (file, "\t(raw 0x");
+         for (j = 0; j < REGISTER_RAW_SIZE (i); j++)
+           {
+             int idx;
+             if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+               idx = j;
+             else
+               idx = REGISTER_RAW_SIZE (i) - 1 - j;
+             fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]);
+           }
+         fprintf_filtered (file, ")");
+       }
+      else
+       {
+         /* Print the register in hex.  */
+         val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+                    file, 'x', 1, 0, Val_pretty_default);
+          /* If not a vector register, print it also according to its
+             natural format.  */
+         if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (i)) == 0)
+           {
+             fprintf_filtered (file, "\t");
+             val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+                        file, 0, 1, 0, Val_pretty_default);
+           }
+       }
+
+      /* Some sparc specific info.  */
+      if (print_register_hook != NULL)
+       print_register_hook (i);
+
+      fprintf_filtered (file, "\n");
+    }
+}
+
+static void
+sparc_print_registers_info (struct gdbarch *gdbarch,
+                           struct ui_file *file,
+                           struct frame_info *frame,
+                           int regnum, int print_all)
+{
+  sparc_print_registers (gdbarch, file, frame, regnum, print_all,
+                        sparc_print_register_hook);
+}
+
+void
+sparc_do_registers_info (int regnum, int all)
+{
+  sparc_print_registers_info (current_gdbarch, gdb_stdout, selected_frame,
+                             regnum, all);
+}
+
+static void
+sparclet_print_registers_info (struct gdbarch *gdbarch,
+                              struct ui_file *file,
+                              struct frame_info *frame,
+                              int regnum, int print_all)
+{
+  sparc_print_registers (gdbarch, file, frame, regnum, print_all, NULL);
+}
+
+void
+sparclet_do_registers_info (int regnum, int all)
+{
+  sparclet_print_registers_info (current_gdbarch, gdb_stdout, selected_frame,
+                                regnum, all);
+}
+
 \f
 int
 gdb_print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
@@ -2087,7 +2241,7 @@ sparc32_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
       for (j = 0; 
           j < m_arg->len && oregnum < 6; 
           j += SPARC_INTREG_SIZE, oregnum++)
-       write_register_gen (O0_REGNUM + oregnum, m_arg->contents + j);
+       deprecated_write_register_gen (O0_REGNUM + oregnum, m_arg->contents + j);
     }
 
   return sp;
@@ -2143,18 +2297,19 @@ sparc_store_return_value (struct type *type, char *valbuf)
       memset (buffer, 0, REGISTER_RAW_SIZE (regno));
       memcpy (buffer + REGISTER_RAW_SIZE (regno) - TYPE_LENGTH (type), valbuf,
              TYPE_LENGTH (type));
-      write_register_gen (regno, buffer);
+      deprecated_write_register_gen (regno, buffer);
     }
   else
-    write_register_bytes (REGISTER_BYTE (regno), valbuf, TYPE_LENGTH (type));
+    deprecated_write_register_bytes (REGISTER_BYTE (regno), valbuf,
+                                    TYPE_LENGTH (type));
 }
 
 extern void
 sparclet_store_return_value (struct type *type, char *valbuf)
 {
   /* Other values are returned in register %o0.  */
-  write_register_bytes (REGISTER_BYTE (O0_REGNUM), valbuf,
-                       TYPE_LENGTH (type));
+  deprecated_write_register_bytes (REGISTER_BYTE (O0_REGNUM), valbuf,
+                                  TYPE_LENGTH (type));
 }
 
 
@@ -2262,12 +2417,13 @@ sparc_target_architecture_hook (const bfd_arch_info_type *ap)
 
 static struct gdbarch * sparc_gdbarch_init (struct gdbarch_info info,
                                            struct gdbarch_list *arches);
+static void sparc_dump_tdep (struct gdbarch *, struct ui_file *);
 
 void
 _initialize_sparc_tdep (void)
 {
   /* Hook us into the gdbarch mechanism.  */
-  register_gdbarch_init (bfd_arch_sparc, sparc_gdbarch_init);
+  gdbarch_register (bfd_arch_sparc, sparc_gdbarch_init, sparc_dump_tdep);
 
   tm_print_insn = gdb_print_insn_sparc;
   tm_print_insn_info.mach = TM_PRINT_INSN_MACH;                /* Selects sparc/sparclite */
@@ -2414,9 +2570,9 @@ sparc64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
              default:
                internal_error (__FILE__, __LINE__, "bad switch");
              }
-             write_register_bytes (REGISTER_BYTE (fpreg),
-                                   VALUE_CONTENTS (args[i]),
-                                   len);
+             deprecated_write_register_bytes (REGISTER_BYTE (fpreg),
+                                              VALUE_CONTENTS (args[i]),
+                                              len);
            }
        }
       else /* all other args go into the first six 'o' registers */
@@ -2427,7 +2583,7 @@ sparc64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
            {
              int oreg = O0_REGNUM + register_counter;
 
-             write_register_gen (oreg, VALUE_CONTENTS (copyarg) + j);
+             deprecated_write_register_gen (oreg, VALUE_CONTENTS (copyarg) + j);
              register_counter += 1;
            }
         }
@@ -2537,7 +2693,7 @@ sparc_print_extra_frame_info (struct frame_info *fi)
 
 /* MULTI_ARCH support */
 
-static char *
+static const char *
 sparc32_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2561,7 +2717,7 @@ sparc32_register_name (int regno)
     return register_names[regno];
 }
 
-static char *
+static const char *
 sparc64_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2593,7 +2749,7 @@ sparc64_register_name (int regno)
     return register_names[regno];
 }
 
-static char *
+static const char *
 sparclite_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2618,7 +2774,7 @@ sparclite_register_name (int regno)
     return register_names[regno];
 }
 
-static char *
+static const char *
 sparclet_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2920,6 +3076,7 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
+  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
   static LONGEST call_dummy_32[] = 
     { 0xbc100001, 0x9de38000, 0xbc100002, 0xbe100003,
@@ -2943,10 +3100,29 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     };
   static LONGEST call_dummy_nil[] = {0};
 
+  /* Try to determine the OS ABI of the object we are loading.  */
+
+  if (info.abfd != NULL)
+    {
+      osabi = gdbarch_lookup_osabi (info.abfd);
+      if (osabi == GDB_OSABI_UNKNOWN)
+       {
+         /* If it's an ELF file, assume it's Solaris.  */
+         if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+           osabi = GDB_OSABI_SOLARIS;
+       }
+    }
+
   /* First see if there is already a gdbarch that can satisfy the request.  */
-  arches = gdbarch_list_lookup_by_info (arches, &info);
-  if (arches != NULL)
-    return arches->gdbarch;
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      /* Make sure the ABI selection matches.  */
+      tdep = gdbarch_tdep (arches->gdbarch);
+      if (tdep && tdep->osabi == osabi)
+       return arches->gdbarch;
+    }
 
   /* None found: is the request for a sparc architecture? */
   if (info.bfd_arch_info->arch != bfd_arch_sparc)
@@ -2956,6 +3132,8 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
   gdbarch = gdbarch_alloc (&info, tdep);
 
+  tdep->osabi = osabi;
+
   /* First set settings that are common for all sparc architectures.  */
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
   set_gdbarch_breakpoint_from_pc (gdbarch, memory_breakpoint_from_pc);
@@ -2966,8 +3144,7 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 1);
   set_gdbarch_decr_pc_after_break (gdbarch, 0);
   set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
-  set_gdbarch_extract_struct_value_address (gdbarch, 
-                                           sparc_extract_struct_value_address);
+  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, sparc_extract_struct_value_address);
   set_gdbarch_fix_call_dummy (gdbarch, sparc_gdbarch_fix_call_dummy);
   set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_fp_regnum (gdbarch, SPARC_FP_REGNUM);
@@ -3026,6 +3203,50 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address);
       set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0x30);
       set_gdbarch_call_dummy_length (gdbarch, 0x38);
+
+      /* NOTE: cagney/2002-04-26: Based from info posted by Peter
+        Schauer around Oct '99.  Briefly, due to aspects of the SPARC
+        ABI, it isn't possible to use ON_STACK with a strictly
+        compliant compiler.
+
+        Peter Schauer writes ...
+
+        No, any call from GDB to a user function returning a
+        struct/union will fail miserably. Try this:
+
+        *NOINDENT*
+        struct x
+        {
+           int a[4];
+         };
+
+        struct x gx;
+
+        struct x
+        sret ()
+        {
+          return gx;
+        }
+
+        main ()
+        {
+          int i;
+          for (i = 0; i < 4; i++)
+            gx.a[i] = i + 1;
+          gx = sret ();
+        }
+        *INDENT*
+
+        Set a breakpoint at the gx = sret () statement, run to it and
+        issue a `print sret()'. It will not succed with your
+        approach, and I doubt that continuing the program will work
+        as well.
+
+        For details of the ABI see the Sparc Architecture Manual.  I
+        have Version 8 (Prentice Hall ISBN 0-13-825001-4) and the
+        calling conventions for functions returning aggregate values
+        are explained in Appendix D.3.  */
+
       set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
       set_gdbarch_call_dummy_words (gdbarch, call_dummy_32);
 #else
@@ -3137,96 +3358,109 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   switch (info.bfd_arch_info->mach)
     {
     case bfd_mach_sparc:
-      set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 72);
       set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
       set_gdbarch_register_name (gdbarch, sparc32_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->has_fpu = 1;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 32 * 4;
       tdep->print_insn_mach = bfd_mach_sparc;
       break;
     case bfd_mach_sparc_sparclet:
-      set_gdbarch_extract_return_value (gdbarch, 
-                                       sparclet_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparclet_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 32 + 32 + 8 + 8 + 8);
       set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4 + 8*4);
       set_gdbarch_register_name (gdbarch, sparclet_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparclet_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparclet_store_return_value);
       tdep->has_fpu = 0;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 0;
       tdep->print_insn_mach = bfd_mach_sparc_sparclet;
       break;
     case bfd_mach_sparc_sparclite:
-      set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 80);
       set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4);
       set_gdbarch_register_name (gdbarch, sparclite_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->has_fpu = 0;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 0;
       tdep->print_insn_mach = bfd_mach_sparc_sparclite;
       break;
     case bfd_mach_sparc_v8plus:
-      set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 72);
       set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
       set_gdbarch_register_name (gdbarch, sparc32_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->print_insn_mach = bfd_mach_sparc;
       tdep->fp_register_bytes = 32 * 4;
       tdep->has_fpu = 1;       /* (all but sparclet and sparclite) */
       break;
     case bfd_mach_sparc_v8plusa:
-      set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 72);
       set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
       set_gdbarch_register_name (gdbarch, sparc32_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->has_fpu = 1;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 32 * 4;
       tdep->print_insn_mach = bfd_mach_sparc;
       break;
     case bfd_mach_sparc_sparclite_le:
-      set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 80);
       set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4);
       set_gdbarch_register_name (gdbarch, sparclite_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->has_fpu = 0;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 0;
       tdep->print_insn_mach = bfd_mach_sparc_sparclite;
       break;
     case bfd_mach_sparc_v9:
-      set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc64_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 125);
       set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8);
       set_gdbarch_register_name (gdbarch, sparc64_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->has_fpu = 1;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 64 * 4;
       tdep->print_insn_mach = bfd_mach_sparc_v9a;
       break;
     case bfd_mach_sparc_v9a:
-      set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
+      set_gdbarch_deprecated_extract_return_value (gdbarch, sparc64_extract_return_value);
       set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
       set_gdbarch_num_regs (gdbarch, 125);
       set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8);
       set_gdbarch_register_name (gdbarch, sparc64_register_name);
-      set_gdbarch_store_return_value (gdbarch, sparc_store_return_value);
+      set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
       tdep->has_fpu = 1;       /* (all but sparclet and sparclite) */
       tdep->fp_register_bytes = 64 * 4;
       tdep->print_insn_mach = bfd_mach_sparc_v9a;
       break;
     }
 
+  /* Hook in OS ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch, osabi);
+
   return gdbarch;
 }
 
+static void
+sparc_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  if (tdep == NULL)
+    return;
+
+  fprintf_unfiltered (file, "sparc_dump_tdep: OS ABI = %s\n",
+                     gdbarch_osabi_name (tdep->osabi));
+}
This page took 0.035918 seconds and 4 git commands to generate.