diff options
-rw-r--r-- | gdb/ChangeLog | 14 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 58 |
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); |