summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/mips-tdep.c58
2 files changed, 68 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 845cfbffe07..0fdd0c4c84f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
2002-09-30 Andrew Cagney <ac131313@redhat.com>
+ * mips-tdep.c (mips_frame_saved_pc): When a generic dummy frame,
+ use frame_unwind_signed_register to obtain the PC.
+ (mips_frame_chain): Handle a generic dummy frame.
+ (mips_init_extra_frame_info): When a generic dummy frame, don't
+ re-compute the frame base.
+ (mips_pop_frame): Handle generic dummy frames.
+ (mips_gdbarch_init): When generic dummy frames, set
+ use_generic_dummy_frames, push_dummy_frame to
+ generic_push_dummy_frame, pc_in_call_dummy to
+ generic_pc_in_call_dummy, and save_dummy_frame_top_of_stack to
+ generic_save_dummy_frame_tos.
+
+2002-09-30 Andrew Cagney <ac131313@redhat.com>
+
* blockframe.c (generic_find_dummy_frame): Rewrite. Only test
against TOP when TOP was explictly set.
(generic_push_dummy_frame): Set TOP to zero.
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 95b288ce6da..627af203712 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -1704,7 +1704,14 @@ mips_frame_saved_pc (struct frame_info *frame)
int pcreg = frame->signal_handler_caller ? PC_REGNUM
: (proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM);
- if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (frame->pc, 0, 0))
+ {
+ LONGEST tmp;
+ frame_unwind_signed_register (frame, PC_REGNUM, &tmp);
+ saved_pc = tmp;
+ }
+ else if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
saved_pc = read_memory_integer (frame->frame - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
else
saved_pc = read_next_frame_reg (frame, pcreg);
@@ -2421,6 +2428,15 @@ mips_frame_chain (struct frame_info *frame)
if ((tmp = SKIP_TRAMPOLINE_CODE (saved_pc)) != 0)
saved_pc = tmp;
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (saved_pc, 0, 0))
+ {
+ /* A dummy frame, uses SP not FP. Get the old SP value. If all
+ is well, frame->frame the bottom of the current frame will
+ contain that value. */
+ return frame->frame;
+ }
+
/* Look up the procedure descriptor for this PC. */
proc_desc = find_proc_desc (saved_pc, frame, 1);
if (!proc_desc)
@@ -2436,8 +2452,10 @@ mips_frame_chain (struct frame_info *frame)
/* The previous frame from a sigtramp frame might be frameless
and have frame size zero. */
&& !frame->signal_handler_caller
- /* Check if this is a call dummy frame. */
- && frame->pc != CALL_DUMMY_ADDRESS ())
+ /* For a generic dummy frame, let get_frame_pointer() unwind a
+ register value saved as part of the dummy frame call. */
+ && !(USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (frame->pc, 0, 0)))
return 0;
else
return get_frame_pointer (frame, proc_desc);
@@ -2467,6 +2485,15 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
if (fci->pc == PROC_LOW_ADDR (proc_desc)
&& !PROC_DESC_IS_DUMMY (proc_desc))
fci->frame = read_next_frame_reg (fci->next, SP_REGNUM);
+ else if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (fci->pc, 0, 0))
+ /* Do not ``fix'' fci->frame. It will have the value of the
+ generic dummy frame's top-of-stack (since the draft
+ fci->frame is obtained by returning the unwound stack
+ pointer) and that is what we want. That way the fci->frame
+ value will match the top-of-stack value that was saved as
+ part of the dummy frames data. */
+ /* Do nothing. */;
else
fci->frame = get_frame_pointer (fci->next, proc_desc);
@@ -3783,9 +3810,16 @@ mips_pop_frame (void)
register int regnum;
struct frame_info *frame = get_current_frame ();
CORE_ADDR new_sp = FRAME_FP (frame);
-
mips_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (frame->pc, 0, 0))
+ {
+ generic_pop_dummy_frame ();
+ flush_cached_frames ();
+ return;
+ }
+
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
if (frame->saved_regs == NULL)
FRAME_INIT_SAVED_REGS (frame);
@@ -5956,22 +5990,38 @@ mips_gdbarch_init (struct gdbarch_info info,
set_gdbarch_call_dummy_p (gdbarch, 1);
set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+#if OLD_STYLE_MIPS_DUMMY_FRAMES
set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+#else
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
+#endif
set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
set_gdbarch_call_dummy_address (gdbarch, mips_call_dummy_address);
set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
+#if OLD_STYLE_MIPS_DUMMY_FRAMES
set_gdbarch_push_dummy_frame (gdbarch, mips_push_dummy_frame);
+#else
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
+#endif
set_gdbarch_pop_frame (gdbarch, mips_pop_frame);
set_gdbarch_call_dummy_start_offset (gdbarch, 0);
set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
set_gdbarch_call_dummy_length (gdbarch, 0);
set_gdbarch_fix_call_dummy (gdbarch, mips_fix_call_dummy);
+#if OLD_STYLE_MIPS_DUMMY_FRAMES
set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+#else
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
+#endif
set_gdbarch_call_dummy_words (gdbarch, mips_call_dummy_words);
set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (mips_call_dummy_words));
set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
set_gdbarch_frame_align (gdbarch, mips_frame_align);
+#if OLD_STYLE_MIPS_DUMMY_FRAMES
+#else
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+#endif
set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
set_gdbarch_register_convert_to_virtual (gdbarch,
mips_register_convert_to_virtual);