/* 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.
#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>
}
}
\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;
/* 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));
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)
{
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);
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
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 */
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);
-}
-