mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
Fix some ARM call dummy problems.
This commit is contained in:
parent
47ede03a41
commit
f079148d61
@ -1,3 +1,13 @@
|
||||
2001-12-20 Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
* arm-tdep.c (arm_init_extra_frame_info): Add special case for
|
||||
call dummies.
|
||||
(arm_frame_saved_pc): Likewise.
|
||||
(arm_push_dummy_frame): Make sure all of the GPRs are saved.
|
||||
(arm_pop_frame): Eliminate special case for call dummies. It
|
||||
is no longer needed now that the frame info is being properly
|
||||
initialized.
|
||||
|
||||
2001-12-20 Michael Snyder <msnyder@redhat.com>
|
||||
|
||||
* maint.c (maintenance_info_sections): Pass string argument to
|
||||
|
102
gdb/arm-tdep.c
102
gdb/arm-tdep.c
@ -1014,6 +1014,7 @@ void
|
||||
arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||
{
|
||||
int reg;
|
||||
CORE_ADDR sp;
|
||||
|
||||
if (fi->next)
|
||||
fi->pc = FRAME_SAVED_PC (fi->next);
|
||||
@ -1033,6 +1034,13 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||
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
|
||||
sp = fi->next->frame - fi->next->frameoffset + fi->next->framesize;
|
||||
|
||||
/* Determine whether or not we're in a sigtramp frame.
|
||||
Unfortunately, it isn't sufficient to test
|
||||
fi->signal_handler_caller because this value is sometimes set
|
||||
@ -1043,28 +1051,45 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||
Note: If an ARM IN_SIGTRAMP method ever needs to compare against
|
||||
the name of the function, the code below will have to be changed
|
||||
to first fetch the name of the function and then pass this name
|
||||
to IN_SIGTRAMP. */
|
||||
to IN_SIGTRAMP. */
|
||||
|
||||
if (SIGCONTEXT_REGISTER_ADDRESS_P ()
|
||||
&& (fi->signal_handler_caller || IN_SIGTRAMP (fi->pc, 0)))
|
||||
{
|
||||
CORE_ADDR sp;
|
||||
|
||||
if (!fi->next)
|
||||
sp = read_sp();
|
||||
else
|
||||
sp = fi->next->frame - fi->next->frameoffset + fi->next->framesize;
|
||||
|
||||
for (reg = 0; reg < NUM_REGS; reg++)
|
||||
fi->fsr.regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg);
|
||||
|
||||
/* FIXME: What about thumb mode? */
|
||||
fi->framereg = SP_REGNUM;
|
||||
fi->frame = read_memory_integer (fi->fsr.regs[fi->framereg], 4);
|
||||
fi->frame = read_memory_integer (fi->fsr.regs[fi->framereg],
|
||||
REGISTER_RAW_SIZE (fi->framereg));
|
||||
fi->framesize = 0;
|
||||
fi->frameoffset = 0;
|
||||
|
||||
}
|
||||
else if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame))
|
||||
{
|
||||
CORE_ADDR rp;
|
||||
CORE_ADDR callers_sp;
|
||||
|
||||
/* Set rp point at the high end of the saved registers. */
|
||||
rp = fi->frame - REGISTER_SIZE;
|
||||
|
||||
/* Fill in addresses of saved registers. */
|
||||
fi->fsr.regs[PS_REGNUM] = rp;
|
||||
rp -= REGISTER_RAW_SIZE (PS_REGNUM);
|
||||
for (reg = PC_REGNUM; reg >= 0; reg--)
|
||||
{
|
||||
fi->fsr.regs[reg] = rp;
|
||||
rp -= REGISTER_RAW_SIZE (reg);
|
||||
}
|
||||
|
||||
callers_sp = read_memory_integer (fi->fsr.regs[SP_REGNUM],
|
||||
REGISTER_RAW_SIZE (SP_REGNUM));
|
||||
fi->framereg = FP_REGNUM;
|
||||
fi->framesize = callers_sp - sp;
|
||||
fi->frameoffset = fi->frame - sp;
|
||||
}
|
||||
else
|
||||
{
|
||||
arm_scan_prologue (fi);
|
||||
@ -1110,6 +1135,11 @@ arm_frame_saved_pc (struct frame_info *fi)
|
||||
return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
|
||||
else
|
||||
#endif
|
||||
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->frameoffset, fi->frame))
|
||||
{
|
||||
return read_memory_integer (fi->fsr.regs[PC_REGNUM], REGISTER_RAW_SIZE (PC_REGNUM));
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE_ADDR pc = arm_find_callers_reg (fi, LR_REGNUM);
|
||||
return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
|
||||
@ -1156,13 +1186,15 @@ arm_push_dummy_frame (void)
|
||||
instruction stores the PC, it stores the address of the stm
|
||||
instruction itself plus 12. */
|
||||
fp = sp = push_word (sp, prologue_start + 12);
|
||||
sp = push_word (sp, read_register (PC_REGNUM)); /* FIXME: was PS_REGNUM */
|
||||
sp = push_word (sp, old_sp);
|
||||
sp = push_word (sp, read_register (FP_REGNUM));
|
||||
|
||||
for (regnum = 10; regnum >= 0; regnum--)
|
||||
/* Push the processor status. */
|
||||
sp = push_word (sp, read_register (PS_REGNUM));
|
||||
|
||||
/* Push all 16 registers starting with r15. */
|
||||
for (regnum = PC_REGNUM; regnum >= 0; regnum--)
|
||||
sp = push_word (sp, read_register (regnum));
|
||||
|
||||
/* Update fp (for both Thumb and ARM) and sp. */
|
||||
write_register (FP_REGNUM, fp);
|
||||
write_register (THUMB_FP_REGNUM, fp);
|
||||
write_register (SP_REGNUM, sp);
|
||||
@ -1377,45 +1409,25 @@ arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
return sp;
|
||||
}
|
||||
|
||||
/* Pop the current frame. So long as the frame info has been initialized
|
||||
properly (see arm_init_extra_frame_info), this code works for dummy frames
|
||||
as well as regular frames. I.e, there's no need to have a special case
|
||||
for dummy frames. */
|
||||
void
|
||||
arm_pop_frame (void)
|
||||
{
|
||||
int regnum;
|
||||
struct frame_info *frame = get_current_frame ();
|
||||
CORE_ADDR old_SP = frame->frame - frame->frameoffset + frame->framesize;
|
||||
|
||||
if (!PC_IN_CALL_DUMMY(frame->pc, frame->frame, read_fp()))
|
||||
{
|
||||
CORE_ADDR old_SP;
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
if (frame->fsr.regs[regnum] != 0)
|
||||
write_register (regnum,
|
||||
read_memory_integer (frame->fsr.regs[regnum],
|
||||
REGISTER_RAW_SIZE (regnum)));
|
||||
|
||||
old_SP = read_register (frame->framereg);
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
if (frame->fsr.regs[regnum] != 0)
|
||||
write_register (regnum,
|
||||
read_memory_integer (frame->fsr.regs[regnum], 4));
|
||||
|
||||
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
|
||||
write_register (SP_REGNUM, old_SP);
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE_ADDR sp;
|
||||
|
||||
sp = read_register (FP_REGNUM);
|
||||
sp -= sizeof(CORE_ADDR); /* we don't care about this first word */
|
||||
|
||||
write_register (PC_REGNUM, read_memory_integer (sp, 4));
|
||||
sp -= sizeof(CORE_ADDR);
|
||||
write_register (SP_REGNUM, read_memory_integer (sp, 4));
|
||||
sp -= sizeof(CORE_ADDR);
|
||||
write_register (FP_REGNUM, read_memory_integer (sp, 4));
|
||||
sp -= sizeof(CORE_ADDR);
|
||||
|
||||
for (regnum = 10; regnum >= 0; regnum--)
|
||||
{
|
||||
write_register (regnum, read_memory_integer (sp, 4));
|
||||
sp -= sizeof(CORE_ADDR);
|
||||
}
|
||||
}
|
||||
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
|
||||
write_register (SP_REGNUM, old_SP);
|
||||
|
||||
flush_cached_frames ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user