2002-09-25 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / sparc-tdep.c
index 0a901b1e2d77bd9dc5fa4bc555f2b62783dacbad..033cc8170bf0740116b8be3c192247ac3b11e0de 100644 (file)
@@ -1,6 +1,8 @@
 /* Target-dependent code for the SPARC for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+   Inc.
 
    This file is part of GDB.
 
 #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>
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
 #endif
 
 #include "gdbcore.h"
 
 #include "symfile.h"   /* for 'entry_point_address' */
 
-/* Prototypes for supply_gregset etc. */
-#include "gregset.h"
-
 /*
  * Some local macros that have multi-arch and non-multi-arch versions:
  */
@@ -109,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.  */
@@ -142,8 +146,7 @@ int bi_endian = 0;
    such as sparc86x, instructions are always big-endian.  */
 
 static unsigned long
-fetch_instruction (pc)
-     CORE_ADDR pc;
+fetch_instruction (CORE_ADDR pc)
 {
   unsigned long retval;
   int i;
@@ -210,9 +213,8 @@ static branch_type isbranch (long, CORE_ADDR, CORE_ADDR *);
    set up a simulated single-step, we undo our damage.  */
 
 void
-sparc_software_single_step (ignore, insert_breakpoints_p)
-     enum target_signal ignore;        /* pid, but we don't need it */
-     int insert_breakpoints_p;
+sparc_software_single_step (enum target_signal ignore, /* pid, but we don't need it */
+                           int insert_breakpoints_p)
 {
   branch_type br;
   CORE_ADDR pc;
@@ -286,9 +288,7 @@ struct frame_extra_info
    been stashed, since their exact position within the frame may vary.  */
 
 void
-sparc_init_extra_frame_info (fromleaf, fi)
-     int fromleaf;
-     struct frame_info *fi;
+sparc_init_extra_frame_info (int fromleaf, struct frame_info *fi)
 {
   char *name;
   CORE_ADDR prologue_start, prologue_end;
@@ -344,7 +344,7 @@ sparc_init_extra_frame_info (fromleaf, fi)
          negative number if a flat frame) to the sp.  FIXME: Does not
          handle large frames which will need more than one instruction
          to adjust the sp.  */
-      insn = fetch_instruction (prologue_start, 4);
+      insn = fetch_instruction (prologue_start);
       if (X_OP (insn) == 2 && X_RD (insn) == 14 && X_OP3 (insn) == 0
          && X_I (insn) && X_SIMM13 (insn) < 0)
        {
@@ -427,18 +427,16 @@ sparc_init_extra_frame_info (fromleaf, fi)
 }
 
 CORE_ADDR
-sparc_frame_chain (frame)
-     struct frame_info *frame;
+sparc_frame_chain (struct frame_info *frame)
 {
   /* Value that will cause FRAME_CHAIN_VALID to not worry about the chain
-     value.  If it realy is zero, we detect it later in
+     value.  If it really is zero, we detect it later in
      sparc_init_prev_frame.  */
   return (CORE_ADDR) 1;
 }
 
 CORE_ADDR
-sparc_extract_struct_value_address (regbuf)
-     char *regbuf;
+sparc_extract_struct_value_address (char *regbuf)
 {
   return extract_address (regbuf + REGISTER_BYTE (O0_REGNUM),
                          REGISTER_RAW_SIZE (O0_REGNUM));
@@ -447,8 +445,7 @@ sparc_extract_struct_value_address (regbuf)
 /* Find the pc saved in frame FRAME.  */
 
 CORE_ADDR
-sparc_frame_saved_pc (frame)
-     struct frame_info *frame;
+sparc_frame_saved_pc (struct frame_info *frame)
 {
   char *buf;
   CORE_ADDR addr;
@@ -524,9 +521,7 @@ sparc_frame_saved_pc (frame)
    difficulty.  */
 
 struct frame_info *
-setup_arbitrary_frame (argc, argv)
-     int argc;
-     CORE_ADDR *argv;
+setup_arbitrary_frame (int argc, CORE_ADDR *argv)
 {
   struct frame_info *frame;
 
@@ -536,7 +531,8 @@ setup_arbitrary_frame (argc, argv)
   frame = create_new_frame (argv[0], 0);
 
   if (!frame)
-    internal_error ("create_new_frame returned invalid frame");
+    internal_error (__FILE__, __LINE__,
+                   "create_new_frame returned invalid frame");
 
   frame->extra_info->bottom = argv[1];
   frame->pc = FRAME_SAVED_PC (frame);
@@ -556,11 +552,8 @@ static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *,
                                   CORE_ADDR *);
 
 static CORE_ADDR
-examine_prologue (start_pc, frameless_p, fi, saved_regs)
-     CORE_ADDR start_pc;
-     int frameless_p;
-     struct frame_info *fi;
-     CORE_ADDR *saved_regs;
+examine_prologue (CORE_ADDR start_pc, int frameless_p, struct frame_info *fi,
+                 CORE_ADDR *saved_regs)
 {
   int insn;
   int dest = -1;
@@ -694,12 +687,36 @@ examine_prologue (start_pc, frameless_p, fi, saved_regs)
   return pc;
 }
 
+/* Advance PC across any function entry prologue instructions to reach
+   some "real" code.  */
+
 CORE_ADDR
-sparc_skip_prologue (start_pc, frameless_p)
-     CORE_ADDR start_pc;
-     int frameless_p;
+sparc_skip_prologue (CORE_ADDR start_pc)
+{
+  struct symtab_and_line sal;
+  CORE_ADDR func_start, func_end;
+
+  /* This is the preferred method, find the end of the prologue by
+     using the debugging information.  */
+  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
+    {
+      sal = find_pc_line (func_start, 0);
+
+      if (sal.end < func_end
+         && start_pc <= sal.end)
+       return sal.end;
+    }
+
+  /* Oh well, examine the code by hand.  */
+  return examine_prologue (start_pc, 0, NULL, NULL);
+}
+
+/* Is the prologue at IP frameless?  */
+
+int
+sparc_prologue_frameless_p (CORE_ADDR ip)
 {
-  return examine_prologue (start_pc, frameless_p, NULL, NULL);
+  return ip == examine_prologue (ip, 1, NULL, NULL);
 }
 
 /* Check instruction at ADDR to see if it is a branch.
@@ -709,9 +726,7 @@ sparc_skip_prologue (start_pc, frameless_p)
    This isn't static as it's used by remote-sa.sparc.c.  */
 
 static branch_type
-isbranch (instruction, addr, target)
-     long instruction;
-     CORE_ADDR addr, *target;
+isbranch (long instruction, CORE_ADDR addr, CORE_ADDR *target)
 {
   branch_type val = not_branch;
   long int offset = 0;         /* Must be signed for sign-extend.  */
@@ -780,13 +795,9 @@ isbranch (instruction, addr, target)
    The argument RAW_BUFFER must point to aligned memory.  */
 
 void
-sparc_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
-     char *raw_buffer;
-     int *optimized;
-     CORE_ADDR *addrp;
-     struct frame_info *frame;
-     int regnum;
-     enum lval_type *lval;
+sparc_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
+                         struct frame_info *frame, int regnum,
+                         enum lval_type *lval)
 {
   struct frame_info *frame1;
   CORE_ADDR addr;
@@ -846,11 +857,21 @@ sparc_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
            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)
-           addr = (frame1->prev->extra_info->bottom
+           /* 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)
-           addr = (frame1->prev->extra_info->bottom
+           /* 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);
          else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8)
@@ -892,11 +913,11 @@ sparc_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
        {
          /* Normal frame.  Local and In registers are saved on stack.  */
          if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8)
-           addr = (frame1->prev->extra_info->bottom
+           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)
-           addr = (frame1->prev->extra_info->bottom
+           addr = (get_prev_frame (frame1)->extra_info->bottom
                    + (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
                    + FRAME_SAVED_L0);
          else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8)
@@ -957,7 +978,7 @@ sparc_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
      (DUMMY_STACK_REG_BUF_SIZE + DUMMY_REG_SAVE_OFFSET)
 
 void
-sparc_push_dummy_frame ()
+sparc_push_dummy_frame (void)
 {
   CORE_ADDR sp, old_sp;
   char *register_temp;
@@ -1005,8 +1026,26 @@ sparc_push_dummy_frame ()
 
   if (strcmp (target_shortname, "sim") != 0)
     {
-      write_fp (old_sp);
-
+      /* NOTE: cagney/2002-04-04: The code below originally contained
+         GDB's _only_ call to write_fp().  That call was eliminated by
+         inlining the corresponding code.  For the 64 bit case, the
+         old function (sparc64_write_fp) did the below although I'm
+         not clear why.  The same goes for why this is only done when
+         the underlying target is a simulator.  */
+      if (GDB_TARGET_IS_SPARC64)
+       {
+         /* Target is a 64 bit SPARC.  */
+         CORE_ADDR oldfp = read_register (FP_REGNUM);
+         if (oldfp & 1)
+           write_register (FP_REGNUM, old_sp - 2047);
+         else
+           write_register (FP_REGNUM, old_sp);
+       }
+      else
+       {
+         /* Target is a 32 bit SPARC.  */
+         write_register (FP_REGNUM, old_sp);
+       }
       /* Set return address register for the call dummy to the current PC.  */
       write_register (I7_REGNUM, read_pc () - 8);
     }
@@ -1068,15 +1107,14 @@ sparc_push_dummy_frame ()
 static void sparc_frame_find_saved_regs (struct frame_info *, CORE_ADDR *);
 
 static void
-sparc_frame_find_saved_regs (fi, saved_regs_addr)
-     struct frame_info *fi;
-     CORE_ADDR *saved_regs_addr;
+sparc_frame_find_saved_regs (struct frame_info *fi, CORE_ADDR *saved_regs_addr)
 {
   register int regnum;
   CORE_ADDR frame_addr = FRAME_FP (fi);
 
   if (!fi)
-    internal_error ("Bad frame info struct in FRAME_FIND_SAVED_REGS");
+    internal_error (__FILE__, __LINE__,
+                   "Bad frame info struct in FRAME_FIND_SAVED_REGS");
 
   memset (saved_regs_addr, 0, NUM_REGS * sizeof (CORE_ADDR));
 
@@ -1183,7 +1221,7 @@ sparc_frame_find_saved_regs (fi, saved_regs_addr)
 /* Definitely see tm-sparc.h for more doc of the frame format here.  */
 
 void
-sparc_pop_frame ()
+sparc_pop_frame (void)
 {
   register struct frame_info *frame = get_current_frame ();
   register CORE_ADDR pc;
@@ -1254,7 +1292,7 @@ sparc_pop_frame ()
 
       char *reg_temp;
 
-      reg_temp = alloca (REGISTER_BYTES);
+      reg_temp = alloca (SPARC_INTREG_SIZE * 16);
 
       read_memory (fsr[I0_REGNUM], raw_buffer, 8 * SPARC_INTREG_SIZE);
 
@@ -1338,8 +1376,7 @@ sparc_pop_frame ()
    a fake insn, step past it.  */
 
 CORE_ADDR
-sparc_pc_adjust (pc)
-     CORE_ADDR pc;
+sparc_pc_adjust (CORE_ADDR pc)
 {
   unsigned long insn;
   char buf[4];
@@ -1366,8 +1403,7 @@ sparc_pc_adjust (pc)
    by hand.  */
 
 CORE_ADDR
-sunos4_skip_trampoline_code (pc)
-     CORE_ADDR pc;
+sunos4_skip_trampoline_code (CORE_ADDR pc)
 {
   unsigned long insn1;
   char buf[4];
@@ -1439,8 +1475,7 @@ sunos4_skip_trampoline_code (pc)
    register values. */
 
 void
-supply_gregset (gregsetp)
-     gdb_gregset_t *gregsetp;
+supply_gregset (gdb_gregset_t *gregsetp)
 {
   prgreg_t *regp = (prgreg_t *) gregsetp;
   int regi, offset = 0;
@@ -1561,9 +1596,7 @@ supply_gregset (gregsetp)
 }
 
 void
-fill_gregset (gregsetp, regno)
-     gdb_gregset_t *gregsetp;
-     int regno;
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
 {
   prgreg_t *regp = (prgreg_t *) gregsetp;
   int regi, offset = 0;
@@ -1643,8 +1676,7 @@ fill_gregset (gregsetp, regno)
    idea of the current floating point register values. */
 
 void
-supply_fpregset (fpregsetp)
-     gdb_fpregset_t *fpregsetp;
+supply_fpregset (gdb_fpregset_t *fpregsetp)
 {
   register int regi;
   char *from;
@@ -1682,9 +1714,7 @@ supply_fpregset (fpregsetp)
 /* This will probably need some changes for sparc64.  */
 
 void
-fill_fpregset (fpregsetp, regno)
-     gdb_fpregset_t *fpregsetp;
-     int regno;
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
 {
   int regi;
   char *to;
@@ -1714,8 +1744,9 @@ fill_fpregset (fpregsetp, regno)
 
 #endif /* USE_PROC_FS */
 
-
-#ifdef GET_LONGJMP_TARGET
+/* Because of Multi-arch, GET_LONGJMP_TARGET is always defined.  So test
+   for a definition of JB_PC.  */
+#ifdef JB_PC
 
 /* Figure out where the longjmp will land.  We expect that we have just entered
    longjmp and haven't yet setup the stack frame, so the args are still in the
@@ -1724,8 +1755,7 @@ fill_fpregset (fpregsetp, regno)
    This routine returns true on success */
 
 int
-get_longjmp_target (pc)
-     CORE_ADDR *pc;
+get_longjmp_target (CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
 #define LONGJMP_TARGET_SIZE 4
@@ -1748,8 +1778,7 @@ get_longjmp_target (pc)
    related to C++ mangling, it is done for C too.  */
 
 char *
-sunpro_static_transform_name (name)
-     char *name;
+sunpro_static_transform_name (char *name)
 {
   char *p;
   if (name[0] == '$')
@@ -1776,9 +1805,7 @@ sunpro_static_transform_name (name)
 static void dump_ccreg (char *, int);
 
 static void
-dump_ccreg (reg, val)
-     char *reg;
-     int val;
+dump_ccreg (char *reg, int val)
 {
   /* page 41 */
   printf_unfiltered ("%s:%s,%s,%s,%s", reg,
@@ -1789,8 +1816,7 @@ dump_ccreg (reg, val)
 }
 
 static char *
-decode_asi (val)
-     int val;
+decode_asi (int val)
 {
   /* page 72 */
   switch (val)
@@ -1833,8 +1859,7 @@ decode_asi (val)
 /* FIXME: Would be nice if this did some fancy things for 32 bit sparc.  */
 
 void
-sparc_print_register_hook (regno)
-     int regno;
+sparc_print_register_hook (int regno)
 {
   ULONGEST val;
 
@@ -1844,8 +1869,8 @@ sparc_print_register_hook (regno)
     {
       char value[16];
 
-      if (!read_relative_register_raw_bytes (regno, value)
-         && !read_relative_register_raw_bytes (regno + 1, value + 4))
+      if (frame_register_read (selected_frame, regno, value)
+         && frame_register_read (selected_frame, regno + 1, value + 4))
        {
          printf_unfiltered ("\t");
          print_floating (value, builtin_type_double, gdb_stdout);
@@ -1853,8 +1878,8 @@ sparc_print_register_hook (regno)
 #if 0                          /* FIXME: gdb doesn't handle long doubles */
       if ((regno & 3) == 0)
        {
-         if (!read_relative_register_raw_bytes (regno + 2, value + 8)
-             && !read_relative_register_raw_bytes (regno + 3, value + 12))
+         if (frame_register_read (selected_frame, regno + 2, value + 8)
+             && frame_register_read (selected_frame, regno + 3, value + 12))
            {
              printf_unfiltered ("\t");
              print_floating (value, builtin_type_long_double, gdb_stdout);
@@ -1873,8 +1898,8 @@ sparc_print_register_hook (regno)
     {
       char value[16];
 
-      if (!read_relative_register_raw_bytes (regno, value)
-         && !read_relative_register_raw_bytes (regno + 1, value + 8))
+      if (frame_register_read (selected_frame, regno, value)
+         && frame_register_read (selected_frame, regno + 1, value + 8))
        {
          printf_unfiltered ("\t");
          print_floating (value, builtin_type_long_double, gdb_stdout);
@@ -2005,9 +2030,7 @@ sparc_print_register_hook (regno)
 }
 \f
 int
-gdb_print_insn_sparc (memaddr, info)
-     bfd_vma memaddr;
-     disassemble_info *info;
+gdb_print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
 {
   /* It's necessary to override mach again because print_insn messes it up. */
   info->mach = TARGET_ARCHITECTURE->mach;
@@ -2019,12 +2042,8 @@ gdb_print_insn_sparc (memaddr, info)
    args are also passed in registers o0 - o5.  */
 
 CORE_ADDR
-sparc32_push_arguments (nargs, args, sp, struct_return, struct_addr)
-     int nargs;
-     value_ptr *args;
-     CORE_ADDR sp;
-     int struct_return;
-     CORE_ADDR struct_addr;
+sparc32_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+                       int struct_return, CORE_ADDR struct_addr)
 {
   int i, j, oregnum;
   int accumulate_size = 0;
@@ -2042,7 +2061,7 @@ sparc32_push_arguments (nargs, args, sp, struct_return, struct_addr)
      and sizes. */
   for (i = 0, m_arg = sparc_args; i < nargs; i++, m_arg++)
     {
-      value_ptr arg = args[i];
+      struct value *arg = args[i];
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       /* Cast argument to long if necessary as the compiler does it too.  */
       switch (TYPE_CODE (arg_type))
@@ -2092,10 +2111,7 @@ sparc32_push_arguments (nargs, args, sp, struct_return, struct_addr)
    into VALBUF.  */
 
 void
-sparc32_extract_return_value (type, regbuf, valbuf)
-     struct type *type;
-     char *regbuf;
-     char *valbuf;
+sparc32_extract_return_value (struct type *type, char *regbuf, char *valbuf)
 {
   int typelen = TYPE_LENGTH (type);
   int regsize = REGISTER_RAW_SIZE (O0_REGNUM);
@@ -2106,7 +2122,7 @@ sparc32_extract_return_value (type, regbuf, valbuf)
     memcpy (valbuf,
            &regbuf[O0_REGNUM * regsize +
                    (typelen >= regsize
-                    || TARGET_BYTE_ORDER == LITTLE_ENDIAN ? 0
+                    || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE ? 0
                     : regsize - typelen)],
            typelen);
 }
@@ -2118,14 +2134,12 @@ sparc32_extract_return_value (type, regbuf, valbuf)
    values are returned in register %o0.  */
 
 void
-sparc_store_return_value (type, valbuf)
-     struct type *type;
-     char *valbuf;
+sparc_store_return_value (struct type *type, char *valbuf)
 {
   int regno;
   char *buffer;
 
-  buffer = alloca(MAX_REGISTER_RAW_SIZE);
+  buffer = alloca (MAX_REGISTER_RAW_SIZE);
 
   if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU)
     /* Floating-point values are returned in the register pair */
@@ -2171,12 +2185,8 @@ sparclet_store_return_value (struct type *type, char *valbuf)
    has already been customized for a different function).  */
 
 void
-sparc_fix_call_dummy (dummy, pc, fun, value_type, using_gcc)
-     char *dummy;
-     CORE_ADDR pc;
-     CORE_ADDR fun;
-     struct type *value_type;
-     int using_gcc;
+sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+                     struct type *value_type, int using_gcc)
 {
   int i;
 
@@ -2187,13 +2197,27 @@ sparc_fix_call_dummy (dummy, pc, fun, value_type, using_gcc)
                           | (((fun - (pc + CALL_DUMMY_CALL_OFFSET)) >> 2)
                              & 0x3fffffff)));
 
-  /* Comply with strange Sun cc calling convention for struct-returning
-     functions.  */
-  if (!using_gcc
-      && (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
-         || TYPE_CODE (value_type) == TYPE_CODE_UNION))
-    store_unsigned_integer (dummy + CALL_DUMMY_CALL_OFFSET + 8, 4,
-                           TYPE_LENGTH (value_type) & 0x1fff);
+  /* If the called function returns an aggregate value, fill in the UNIMP
+     instruction containing the size of the returned aggregate return value,
+     which follows the call instruction.
+     For details see the SPARC Architecture Manual Version 8, Appendix D.3.
+
+     Adjust the call_dummy_breakpoint_offset for the bp_call_dummy breakpoint
+     to the proper address in the call dummy, so that `finish' after a stop
+     in a call dummy works.
+     Tweeking current_gdbarch is not an optimal solution, but the call to
+     sparc_fix_call_dummy is immediately followed by a call to run_stack_dummy,
+     which is the only function where dummy_breakpoint_offset is actually
+     used, if it is non-zero.  */
+  if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
+       || TYPE_CODE (value_type) == TYPE_CODE_UNION)
+    {
+      store_unsigned_integer (dummy + CALL_DUMMY_CALL_OFFSET + 8, 4,
+                             TYPE_LENGTH (value_type) & 0x1fff);
+      set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 0x30);
+    }
+  else
+    set_gdbarch_call_dummy_breakpoint_offset (current_gdbarch, 0x2c);
 
   if (!(GDB_TARGET_IS_SPARC64))
     {
@@ -2229,22 +2253,14 @@ sparc_fix_call_dummy (dummy, pc, fun, value_type, using_gcc)
 /* Set target byte order based on machine type. */
 
 static int
-sparc_target_architecture_hook (ap)
-     const bfd_arch_info_type *ap;
+sparc_target_architecture_hook (const bfd_arch_info_type *ap)
 {
   int i, j;
 
   if (ap->mach == bfd_mach_sparc_sparclite_le)
     {
-      if (TARGET_BYTE_ORDER_SELECTABLE_P)
-       {
-         target_byte_order = LITTLE_ENDIAN;
-         bi_endian = 1;
-       }
-      else
-       {
-         warning ("This GDB does not support little endian sparclite.");
-       }
+      target_byte_order = BFD_ENDIAN_LITTLE;
+      bi_endian = 1;
     }
   else
     bi_endian = 0;
@@ -2258,12 +2274,13 @@ sparc_target_architecture_hook (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 ()
+_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 */
@@ -2294,8 +2311,7 @@ sparc64_read_fp (void)
 }
 
 void
-sparc64_write_sp (val)
-     CORE_ADDR val;
+sparc64_write_sp (CORE_ADDR val)
 {
   CORE_ADDR oldsp = read_register (SP_REGNUM);
   if (oldsp & 1)
@@ -2304,17 +2320,6 @@ sparc64_write_sp (val)
     write_register (SP_REGNUM, val);
 }
 
-void
-sparc64_write_fp (val)
-     CORE_ADDR val;
-{
-  CORE_ADDR oldfp = read_register (FP_REGNUM);
-  if (oldfp & 1)
-    write_register (FP_REGNUM, val - 2047);
-  else
-    write_register (FP_REGNUM, val);
-}
-
 /* The SPARC 64 ABI passes floating-point arguments in FP0 to FP31,
    and all other arguments in O0 to O5.  They are also copied onto
    the stack in the correct places.  Apparently (empirically), 
@@ -2330,12 +2335,8 @@ sparc64_write_fp (val)
    int and float, we will waste every other register of both types.  */
 
 CORE_ADDR
-sparc64_push_arguments (nargs, args, sp, struct_return, struct_retaddr)
-     int nargs;
-     value_ptr *args;
-     CORE_ADDR sp;
-     int struct_return;
-     CORE_ADDR struct_retaddr;
+sparc64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+                       int struct_return, CORE_ADDR struct_retaddr)
 {
   int i, j, register_counter = 0;
   CORE_ADDR tempsp;
@@ -2349,7 +2350,7 @@ sparc64_push_arguments (nargs, args, sp, struct_return, struct_retaddr)
   for (i = nargs - 1; i >= 0; i--)
     {
       int len = TYPE_LENGTH (check_typedef (VALUE_TYPE (args[i])));
-      value_ptr copyarg = args[i];
+      struct value *copyarg = args[i];
       int copylen = len;
 
       if (copylen < SPARC_INTREG_SIZE)
@@ -2375,7 +2376,7 @@ sparc64_push_arguments (nargs, args, sp, struct_return, struct_retaddr)
   for (i = 0; i < nargs; i++)
     {
       int len = TYPE_LENGTH (check_typedef (VALUE_TYPE (args[i])));
-      value_ptr copyarg = args[i];
+      struct value *copyarg = args[i];
       enum type_code typecode = TYPE_CODE (VALUE_TYPE (args[i]));
       int copylen = len;
 
@@ -2423,6 +2424,8 @@ sparc64_push_arguments (nargs, args, sp, struct_return, struct_retaddr)
                fpreg = FP0_REGNUM + 2 * register_counter;
                register_counter += 2;
                break;
+             default:
+               internal_error (__FILE__, __LINE__, "bad switch");
              }
              write_register_bytes (REGISTER_BYTE (fpreg),
                                    VALUE_CONTENTS (args[i]),
@@ -2449,11 +2452,8 @@ sparc64_push_arguments (nargs, args, sp, struct_return, struct_retaddr)
    returned in f0-f3). */
 
 void
-sp64_extract_return_value (type, regbuf, valbuf, bitoffset)
-     struct type *type;
-     char *regbuf;
-     char *valbuf;
-     int bitoffset;
+sp64_extract_return_value (struct type *type, char *regbuf, char *valbuf,
+                          int bitoffset)
 {
   int typelen = TYPE_LENGTH (type);
   int regsize = REGISTER_RAW_SIZE (O0_REGNUM);
@@ -2550,7 +2550,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[] = 
@@ -2574,7 +2574,7 @@ sparc32_register_name (int regno)
     return register_names[regno];
 }
 
-static char *
+static const char *
 sparc64_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2606,7 +2606,7 @@ sparc64_register_name (int regno)
     return register_names[regno];
 }
 
-static char *
+static const char *
 sparclite_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2631,7 +2631,7 @@ sparclite_register_name (int regno)
     return register_names[regno];
 }
 
-static char *
+static const char *
 sparclet_register_name (int regno)
 {
   static char *register_names[] = 
@@ -2815,18 +2815,6 @@ sparc64_register_byte (int regno)
     return 64 * 8 + (regno - 80) * 8;
 }
 
-/* Advance PC across any function entry prologue instructions to reach
-   some "real" code.  SKIP_PROLOGUE_FRAMELESS_P advances the PC past
-   some of the prologue, but stops as soon as it knows that the
-   function has a frame.  Its result is equal to its input PC if the
-   function is frameless, unequal otherwise.  */
-
-static CORE_ADDR
-sparc_gdbarch_skip_prologue (CORE_ADDR ip)
-{
-  return examine_prologue (ip, 0, NULL, NULL);
-}
-
 /* Immediately after a function call, return the saved pc.
    Can't go through the frames for this because on some machines
    the new frame is not set up until the new function executes
@@ -2858,14 +2846,6 @@ sparc_frame_init_saved_regs (struct frame_info *fi_ignored)
 {      /* no-op */
 }
 
-/* The frame address: stored in the 'frame' field of the frame_info.  */
-
-static CORE_ADDR
-sparc_frame_address (struct frame_info *fi)
-{
-  return fi->frame;
-}
-
 /* gdbarch fix call dummy:
    All this function does is rearrange the arguments before calling
    sparc_fix_call_dummy (which does the real work).  */
@@ -2953,6 +2933,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,
@@ -2976,19 +2957,40 @@ 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_architecture != bfd_arch_sparc)
+  if (info.bfd_arch_info->arch != bfd_arch_sparc)
     return NULL;       /* No; then it's not for us.  */
 
   /* Yes: create a new gdbarch for the specified machine type.  */
   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);
@@ -2999,22 +3001,20 @@ 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);
   set_gdbarch_fp0_regnum (gdbarch, SPARC_FP0_REGNUM);
-  set_gdbarch_frame_args_address (gdbarch, sparc_frame_address);
+  set_gdbarch_frame_args_address (gdbarch, default_frame_address);
   set_gdbarch_frame_chain (gdbarch, sparc_frame_chain);
   set_gdbarch_frame_init_saved_regs (gdbarch, sparc_frame_init_saved_regs);
-  set_gdbarch_frame_locals_address (gdbarch, sparc_frame_address);
+  set_gdbarch_frame_locals_address (gdbarch, default_frame_address);
   set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
   set_gdbarch_frame_saved_pc (gdbarch, sparc_frame_saved_pc);
   set_gdbarch_frameless_function_invocation (gdbarch, 
                                             frameless_look_for_prologue);
   set_gdbarch_get_saved_register (gdbarch, sparc_get_saved_register);
-  set_gdbarch_ieee_float (gdbarch, 1);
   set_gdbarch_init_extra_frame_info (gdbarch, sparc_init_extra_frame_info);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
@@ -3022,11 +3022,6 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
   set_gdbarch_max_register_raw_size (gdbarch, 8);
   set_gdbarch_max_register_virtual_size (gdbarch, 8);
-#ifdef DO_CALL_DUMMY_ON_STACK
-  set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
-#else
-  set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
-#endif
   set_gdbarch_pop_frame (gdbarch, sparc_pop_frame);
   set_gdbarch_push_return_address (gdbarch, sparc_push_return_address);
   set_gdbarch_push_dummy_frame (gdbarch, sparc_push_dummy_frame);
@@ -3039,8 +3034,9 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_reg_struct_has_addr (gdbarch, sparc_reg_struct_has_addr);
   set_gdbarch_return_value_on_stack (gdbarch, sparc_return_value_on_stack);
   set_gdbarch_saved_pc_after_call (gdbarch, sparc_saved_pc_after_call);
+  set_gdbarch_prologue_frameless_p (gdbarch, sparc_prologue_frameless_p);
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
-  set_gdbarch_skip_prologue (gdbarch, sparc_gdbarch_skip_prologue);
+  set_gdbarch_skip_prologue (gdbarch, sparc_skip_prologue);
   set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM);
   set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
   set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
@@ -3060,12 +3056,58 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       /* 32-bit machine types: */
 
 #ifdef SPARC32_CALL_DUMMY_ON_STACK
+      set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
       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
+      set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
       set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
       set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
       set_gdbarch_call_dummy_length (gdbarch, 0);
@@ -3099,7 +3141,6 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_store_struct_return (gdbarch, sparc32_store_struct_return);
       set_gdbarch_use_struct_convention (gdbarch, 
                                         generic_use_struct_convention);
-      set_gdbarch_write_fp (gdbarch, generic_target_write_fp);
       set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
       tdep->y_regnum = SPARC32_Y_REGNUM;
       tdep->fp_max_regnum = SPARC_FP0_REGNUM + 32;
@@ -3114,6 +3155,7 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     default:   /* Any new machine type is likely to be 64-bit.  */
 
 #ifdef SPARC64_CALL_DUMMY_ON_STACK
+      set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
       set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address);
       set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 8 * 4);
       set_gdbarch_call_dummy_length (gdbarch, 192);
@@ -3121,6 +3163,7 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_call_dummy_start_offset (gdbarch, 148);
       set_gdbarch_call_dummy_words (gdbarch, call_dummy_64);
 #else
+      set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
       set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
       set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
       set_gdbarch_call_dummy_length (gdbarch, 0);
@@ -3156,7 +3199,6 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_store_struct_return (gdbarch, sparc64_store_struct_return);
       set_gdbarch_use_struct_convention (gdbarch, 
                                         sparc64_use_struct_convention);
-      set_gdbarch_write_fp (gdbarch, sparc64_write_fp);
       set_gdbarch_write_sp (gdbarch, sparc64_write_sp);
       tdep->y_regnum = SPARC64_Y_REGNUM;
       tdep->fp_max_regnum = SPARC_FP0_REGNUM + 48;
@@ -3173,96 +3215,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.037632 seconds and 4 git commands to generate.