* corelow.c, exec.c, inftarg.c, m3-nat.c, op50-rom.c, procfs.c,
[deliverable/binutils-gdb.git] / gdb / sparc-tdep.c
index dc7b1910ba92dc19bba2c90a60f3c45925cb027e..a0cb2cc11802d3a780fff3cf6fdb2be1f54f36d2 100644 (file)
@@ -1,5 +1,6 @@
 /* Target-dependent code for the SPARC for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -22,10 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "inferior.h"
 #include "obstack.h"
 #include "target.h"
-#include "ieee-float.h"
-
-#include "symfile.h" /* for objfiles.h */
-#include "objfiles.h" /* for find_pc_section */
+#include "value.h"
 
 #ifdef USE_PROC_FS
 #include <sys/procfs.h>
@@ -131,9 +129,6 @@ single_step (ignore)
     }
 }
 \f
-#define        FRAME_SAVED_L0  0                           /* Byte offset from SP */
-#define        FRAME_SAVED_I0  (8 * REGISTER_RAW_SIZE (0)) /* Byte offset from SP */
-
 CORE_ADDR
 sparc_frame_chain (thisframe)
      FRAME thisframe;
@@ -161,12 +156,44 @@ sparc_extract_struct_value_address (regbuf)
 /* Find the pc saved in frame FRAME.  */
 
 CORE_ADDR
-frame_saved_pc (frame)
+sparc_frame_saved_pc (frame)
      FRAME frame;
 {
   char buf[MAX_REGISTER_RAW_SIZE];
   CORE_ADDR addr;
 
+  if (frame->signal_handler_caller)
+    {
+      /* This is the signal trampoline frame.
+        Get the saved PC from the sigcontext structure.  */
+
+#ifndef SIGCONTEXT_PC_OFFSET
+#define SIGCONTEXT_PC_OFFSET 12
+#endif
+
+      CORE_ADDR sigcontext_addr;
+      char scbuf[TARGET_PTR_BIT / HOST_CHAR_BIT];
+      int saved_pc_offset = SIGCONTEXT_PC_OFFSET;
+      char *name = NULL;
+
+      /* Solaris2 ucbsigvechandler passes a pointer to a sigcontext
+        as the third parameter.  The offset to the saved pc is 12.  */
+      find_pc_partial_function (frame->pc, &name,
+                               (CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
+      if (name && STREQ (name, "ucbsigvechandler"))
+       saved_pc_offset = 12;
+
+      /* The sigcontext address is contained in register O2.  */
+      get_saved_register (buf, (int *)NULL, (CORE_ADDR *)NULL,
+                         frame, O0_REGNUM + 2, (enum lval_type *)NULL);
+      sigcontext_addr = extract_address (buf, REGISTER_RAW_SIZE (O0_REGNUM));
+
+      /* Don't cause a memory_error when accessing sigcontext in case the
+        stack layout has changed or the stack is corrupt.  */
+      target_read_memory (sigcontext_addr + saved_pc_offset,
+                         scbuf, sizeof (scbuf));
+      return extract_address (scbuf, sizeof (scbuf));
+    }
   addr = (frame->bottom + FRAME_SAVED_I0 +
          REGISTER_RAW_SIZE (I7_REGNUM) * (I7_REGNUM - I0_REGNUM));
   read_memory (addr, buf, REGISTER_RAW_SIZE (I7_REGNUM));
@@ -402,7 +429,8 @@ sparc_frame_find_saved_regs (fi, saved_regs_addr)
       frame = fi->bottom ?
        fi->bottom : read_register (SP_REGNUM);
       for (regnum = L0_REGNUM; regnum < L0_REGNUM+16; regnum++)
-       saved_regs_addr->regs[regnum] = frame + (regnum-L0_REGNUM) * 4;
+       saved_regs_addr->regs[regnum] =
+         frame + (regnum - L0_REGNUM) * REGISTER_RAW_SIZE (L0_REGNUM);
     }
   if (fi->next)
     {
@@ -412,7 +440,8 @@ sparc_frame_find_saved_regs (fi, saved_regs_addr)
         fi->next->bottom :
         read_register (SP_REGNUM));
       for (regnum = O0_REGNUM; regnum < O0_REGNUM+8; regnum++)
-       saved_regs_addr->regs[regnum] = next_next_frame + regnum * 4;
+       saved_regs_addr->regs[regnum] =
+         next_next_frame + regnum * REGISTER_RAW_SIZE (O0_REGNUM);
     }
   /* Otherwise, whatever we would get from ptrace(GETREGS) is accurate */
   saved_regs_addr->regs[SP_REGNUM] = FRAME_FP (fi);
@@ -543,13 +572,11 @@ sparc_pop_frame ()
   else if (fsr.regs[I7_REGNUM])
     {
       /* Return address in %i7 -- adjust it, then restore PC and NPC from it */
-      pc = PC_ADJUST (read_memory_integer (fsr.regs[I7_REGNUM], 4));
+      pc = PC_ADJUST ((CORE_ADDR) read_memory_integer (fsr.regs[I7_REGNUM], 4));
       write_register (PC_REGNUM,  pc);
       write_register (NPC_REGNUM, pc + 4);
     }
   flush_cached_frames ();
-  set_current_frame ( create_new_frame (read_register (FP_REGNUM),
-                                       read_pc ()));
 }
 
 /* On the Sun 4 under SunOS, the compile will leave a fake insn which
@@ -571,16 +598,6 @@ sparc_pc_adjust(pc)
   else
     return pc+8;
 }
-
-
-/* Structure of SPARC extended floating point numbers.
-   This information is not currently used by GDB, since no current SPARC
-   implementations support extended float.  */
-
-const struct ext_format ext_format_sparc = {
-/* tot sbyte smask expbyte manbyte */
-   16, 0,    0x80, 0,1,           4,8,         /* sparc */
-};
 \f
 #ifdef USE_PROC_FS     /* Target dependent support for /proc */
 
@@ -762,24 +779,3 @@ get_longjmp_target(pc)
   return 1;
 }
 #endif /* GET_LONGJMP_TARGET */
-
-/* So far used only for sparc solaris.  In sparc solaris, we recognize
-   a trampoline by it's section name.  That is, if the pc is in a
-   section named ".plt" then we are in a trampline.  */
-
-int
-in_solib_trampoline(pc, name)
-     CORE_ADDR pc;
-     char *name;
-{
-  struct obj_section *s;
-  int retval = 0;
-  
-  s = find_pc_section(pc);
-  
-  retval = (s != NULL
-           && s->sec_ptr->name != NULL
-           && STREQ (s->sec_ptr->name, ".plt"));
-  return(retval);
-}
-
This page took 0.024709 seconds and 4 git commands to generate.