* arm-tdep.c (arm_skip_prologue): Handle generic dummy frames.

(thumb_scan_prologue): Ditto.
(arm_find_callers_reg): Ditto.
(arm_frame_chain): Ditto.
(arm_init_extra_frame_info): Ditto.
(arm_frame_saved_pc): Ditto.
(arm_pop_frame): Ditto.
(arm_push_return_address): New function.
(arm_gdbarch_init): Initialize use_generic_dummy_frames,
call_dummy_location, call_dummy_breakpoint_offset_p,
call_dummy_breakpoint_offset, call_dummy_p,
call_dummy_stack_adjust_p, call_dummy_words,
sizeof_call_dummy_words, call_dummy_start_offset,
call_dummy_length, fix_call_dummy, pc_in_call_dummy,
call_dummy_address, push_return_address and push_dummy_frame for
generic dummy frames.
This commit is contained in:
Andrew Cagney 2002-05-08 01:35:51 +00:00
parent 2b8a5373e1
commit 848cfffbc5
2 changed files with 123 additions and 48 deletions

View File

@ -1,3 +1,22 @@
2002-05-07 Andrew Cagney <ac131313@redhat.com>
* arm-tdep.c (arm_skip_prologue): Handle generic dummy frames.
(thumb_scan_prologue): Ditto.
(arm_find_callers_reg): Ditto.
(arm_frame_chain): Ditto.
(arm_init_extra_frame_info): Ditto.
(arm_frame_saved_pc): Ditto.
(arm_pop_frame): Ditto.
(arm_push_return_address): New function.
(arm_gdbarch_init): Initialize use_generic_dummy_frames,
call_dummy_location, call_dummy_breakpoint_offset_p,
call_dummy_breakpoint_offset, call_dummy_p,
call_dummy_stack_adjust_p, call_dummy_words,
sizeof_call_dummy_words, call_dummy_start_offset,
call_dummy_length, fix_call_dummy, pc_in_call_dummy,
call_dummy_address, push_return_address and push_dummy_frame for
generic dummy frames.
2002-05-07 Jason Thorpe <thorpej@wasabisystems.com>
* sh-tdep.c (sh_nofp_frame_init_saved_regs): Fix error in

View File

@ -421,6 +421,11 @@ arm_skip_prologue (CORE_ADDR pc)
char *func_name;
struct symtab_and_line sal;
/* If we're in a dummy frame, don't even try to skip the prologue. */
if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (pc, 0, 0))
return pc;
/* See what the symbol table says. */
if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
@ -553,6 +558,12 @@ thumb_scan_prologue (struct frame_info *fi)
int findmask = 0;
int i;
/* Don't try to scan dummy frames. */
if (USE_GENERIC_DUMMY_FRAMES
&& fi != NULL
&& PC_IN_CALL_DUMMY (fi->pc, 0, 0))
return;
if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
{
struct symtab_and_line sal = find_pc_line (prologue_start, 0);
@ -990,16 +1001,27 @@ arm_scan_prologue (struct frame_info *fi)
static CORE_ADDR
arm_find_callers_reg (struct frame_info *fi, int regnum)
{
/* NOTE: cagney/2002-05-03: This function really shouldn't be
needed. Instead the (still being written) register unwind
function could be called directly. */
for (; fi; fi = fi->next)
#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
return generic_read_register_dummy (fi->pc, fi->frame, regnum);
else
#endif
if (fi->saved_regs[regnum] != 0)
return read_memory_integer (fi->saved_regs[regnum],
REGISTER_RAW_SIZE (regnum));
{
if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (fi->pc, 0, 0))
{
return generic_read_register_dummy (fi->pc, fi->frame, regnum);
}
else if (fi->saved_regs[regnum] != 0)
{
/* NOTE: cagney/2002-05-03: This would normally need to
handle ARM_SP_REGNUM as a special case as, according to
the frame.h comments, saved_regs[SP_REGNUM] contains the
SP value not its address. It appears that the ARM isn't
doing this though. */
return read_memory_integer (fi->saved_regs[regnum],
REGISTER_RAW_SIZE (regnum));
}
}
return read_register (regnum);
}
/* Function: frame_chain Given a GDB frame, determine the address of
@ -1011,34 +1033,19 @@ arm_find_callers_reg (struct frame_info *fi, int regnum)
static CORE_ADDR
arm_frame_chain (struct frame_info *fi)
{
#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
CORE_ADDR fn_start, callers_pc, fp;
/* Is this a dummy frame? */
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
return fi->frame; /* dummy frame same as caller's frame */
/* Is caller-of-this a dummy frame? */
callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */
fp = arm_find_callers_reg (fi, ARM_FP_REGNUM);
if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
return fp; /* dummy frame's frame may bear no relation to ours */
if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
if (fn_start == entry_point_address ())
return 0; /* in _start fn, don't chain further */
#endif
CORE_ADDR caller_pc, fn_start;
CORE_ADDR caller_pc;
int framereg = fi->extra_info->framereg;
if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (fi->pc, 0, 0))
/* A generic call dummy's frame is the same as caller's. */
return fi->frame;
if (fi->pc < LOWEST_PC)
return 0;
/* If the caller is the startup code, we're at the end of the chain. */
caller_pc = FRAME_SAVED_PC (fi);
if (find_pc_partial_function (caller_pc, 0, &fn_start, 0))
if (fn_start == entry_point_address ())
return 0;
/* If the caller is Thumb and the caller is ARM, or vice versa,
the frame register of the caller is different from ours.
@ -1109,24 +1116,16 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
memset (fi->saved_regs, '\000', sizeof fi->saved_regs);
#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
{
/* We need to setup fi->frame here because run_stack_dummy gets
it wrong by assuming it's always FP. */
fi->frame = generic_read_register_dummy (fi->pc, fi->frame,
ARM_SP_REGNUM);
fi->extra_info->framesize = 0;
fi->extra_info->frameoffset = 0;
return;
}
else
#endif
/* Compute stack pointer for this frame. We use this value for both
the sigtramp and call dummy cases. */
if (!fi->next)
sp = read_sp();
else if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
/* For generic dummy frames, pull the value direct from the frame.
Having an unwind function to do this would be nice. */
sp = generic_read_register_dummy (fi->next->pc, fi->next->frame,
ARM_SP_REGNUM);
else
sp = (fi->next->frame - fi->next->extra_info->frameoffset
+ fi->next->extra_info->framesize);
@ -1188,6 +1187,11 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
if (!fi->next)
/* This is the innermost frame? */
fi->frame = read_register (fi->extra_info->framereg);
else if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
/* Next inner most frame is a dummy, just grab its frame.
Dummy frames always have the same FP as their caller. */
fi->frame = fi->next->frame;
else if (fi->extra_info->framereg == ARM_FP_REGNUM
|| fi->extra_info->framereg == THUMB_FP_REGNUM)
{
@ -1224,11 +1228,11 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
static CORE_ADDR
arm_frame_saved_pc (struct frame_info *fi)
{
#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
/* If a dummy frame, pull the PC out of the frame's register buffer. */
if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (fi->pc, 0, 0))
return generic_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM);
else
#endif
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset,
fi->frame))
{
@ -1270,6 +1274,16 @@ arm_frame_init_saved_regs (struct frame_info *fip)
arm_init_extra_frame_info (0, fip);
}
/* Set the return address for a generic dummy frame. ARM uses the
entry point. */
static CORE_ADDR
arm_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
write_register (ARM_LR_REGNUM, CALL_DUMMY_ADDRESS ());
return sp;
}
/* Push an empty stack frame, to record the current PC, etc. */
static void
@ -1524,6 +1538,14 @@ arm_pop_frame (void)
CORE_ADDR old_SP = (frame->frame - frame->extra_info->frameoffset
+ frame->extra_info->framesize);
if (USE_GENERIC_DUMMY_FRAMES
&& PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
{
generic_pop_dummy_frame ();
flush_cached_frames ();
return;
}
for (regnum = 0; regnum < NUM_REGS; regnum++)
if (frame->saved_regs[regnum] != 0)
write_register (regnum,
@ -2893,6 +2915,11 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->lowest_pc = 0x20;
tdep->jb_pc = -1; /* Longjump support not enabled by default. */
#if OLD_STYLE_ARM_DUMMY_FRAMES
/* NOTE: cagney/2002-05-07: Enable the below to restore the old ARM
specific (non-generic) dummy frame code. Might be useful if
there appears to be a problem with the generic dummy frame
mechanism that replaced it. */
set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
/* Call dummy code. */
@ -2912,6 +2939,27 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_fix_call_dummy (gdbarch, arm_fix_call_dummy);
set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
#else
set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
set_gdbarch_call_dummy_p (gdbarch, 1);
set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words);
set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
set_gdbarch_call_dummy_start_offset (gdbarch, 0);
set_gdbarch_call_dummy_length (gdbarch, 0);
set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
set_gdbarch_push_return_address (gdbarch, arm_push_return_address);
#endif
set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
set_gdbarch_push_arguments (gdbarch, arm_push_arguments);
@ -2931,7 +2979,15 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_frame_num_args (gdbarch, arm_frame_num_args);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_frame_init_saved_regs (gdbarch, arm_frame_init_saved_regs);
#if OLD_STYLE_ARM_DUMMY_FRAMES
/* NOTE: cagney/2002-05-07: Enable the below to restore the old ARM
specific (non-generic) dummy frame code. Might be useful if
there appears to be a problem with the generic dummy frame
mechanism that replaced it. */
set_gdbarch_push_dummy_frame (gdbarch, arm_push_dummy_frame);
#else
set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
#endif
set_gdbarch_pop_frame (gdbarch, arm_pop_frame);
/* Address manipulation. */