2003-03-05 Andrew Cagney <cagney@redhat.com>
* d10v-tdep.c (struct d10v_unwind_cache): Add field "base". (d10v_frame_unwind_cache): Rewrite code computing the base and SP. Do not use d10v_read_sp or d10v_read_fp when obtaining register values.
This commit is contained in:
parent
0d84311632
commit
ceea51452a
|
@ -1,3 +1,10 @@
|
||||||
|
2003-03-05 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
|
* d10v-tdep.c (struct d10v_unwind_cache): Add field "base".
|
||||||
|
(d10v_frame_unwind_cache): Rewrite code computing the base and SP.
|
||||||
|
Do not use d10v_read_sp or d10v_read_fp when obtaining register
|
||||||
|
values.
|
||||||
|
|
||||||
2003-03-05 Andrew Cagney <cagney@redhat.com>
|
2003-03-05 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
* d10v-tdep.c (struct frame_extra_info): Delete unused structure.
|
* d10v-tdep.c (struct frame_extra_info): Delete unused structure.
|
||||||
|
|
|
@ -610,6 +610,8 @@ d10v_skip_prologue (CORE_ADDR pc)
|
||||||
struct d10v_unwind_cache
|
struct d10v_unwind_cache
|
||||||
{
|
{
|
||||||
CORE_ADDR return_pc;
|
CORE_ADDR return_pc;
|
||||||
|
/* The frame's base. Used when constructing a frame ID. */
|
||||||
|
CORE_ADDR base;
|
||||||
int size;
|
int size;
|
||||||
CORE_ADDR *saved_regs;
|
CORE_ADDR *saved_regs;
|
||||||
/* How far the SP and r11 (FP) have been offset from the start of
|
/* How far the SP and r11 (FP) have been offset from the start of
|
||||||
|
@ -706,7 +708,9 @@ struct d10v_unwind_cache *
|
||||||
d10v_frame_unwind_cache (struct frame_info *fi,
|
d10v_frame_unwind_cache (struct frame_info *fi,
|
||||||
void **cache)
|
void **cache)
|
||||||
{
|
{
|
||||||
CORE_ADDR fp, pc;
|
CORE_ADDR pc;
|
||||||
|
ULONGEST prev_sp;
|
||||||
|
ULONGEST this_base;
|
||||||
unsigned long op;
|
unsigned long op;
|
||||||
unsigned short op1, op2;
|
unsigned short op1, op2;
|
||||||
int i;
|
int i;
|
||||||
|
@ -721,8 +725,6 @@ d10v_frame_unwind_cache (struct frame_info *fi,
|
||||||
|
|
||||||
info->size = 0;
|
info->size = 0;
|
||||||
info->return_pc = 0;
|
info->return_pc = 0;
|
||||||
|
|
||||||
fp = get_frame_base (fi);
|
|
||||||
info->sp_offset = 0;
|
info->sp_offset = 0;
|
||||||
|
|
||||||
pc = get_pc_function_start (get_frame_pc (fi));
|
pc = get_pc_function_start (get_frame_pc (fi));
|
||||||
|
@ -780,13 +782,43 @@ d10v_frame_unwind_cache (struct frame_info *fi,
|
||||||
|
|
||||||
info->size = -info->sp_offset;
|
info->size = -info->sp_offset;
|
||||||
|
|
||||||
if (!(fp & 0xffff))
|
/* Compute the frame's base, and the previous frame's SP. */
|
||||||
fp = d10v_read_sp ();
|
if (info->uses_frame)
|
||||||
|
{
|
||||||
|
/* The SP was moved to the FP. This indicates that a new frame
|
||||||
|
was created. Get THIS frame's FP value by unwinding it from
|
||||||
|
the next frame. */
|
||||||
|
frame_read_unsigned_register (fi, FP_REGNUM, &this_base);
|
||||||
|
/* The FP points at the last saved register. Adjust the FP back
|
||||||
|
to before the first saved register giving the SP. */
|
||||||
|
prev_sp = this_base + info->size;
|
||||||
|
}
|
||||||
|
else if (info->saved_regs[SP_REGNUM])
|
||||||
|
{
|
||||||
|
/* The SP was saved (which is very unusual), the frame base is
|
||||||
|
just the PREV's frame's TOP-OF-STACK. */
|
||||||
|
this_base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM],
|
||||||
|
register_size (current_gdbarch,
|
||||||
|
SP_REGNUM));
|
||||||
|
prev_sp = this_base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Assume that the FP is this frame's SP but with that pushed
|
||||||
|
stack space added back. */
|
||||||
|
frame_read_unsigned_register (fi, SP_REGNUM, &this_base);
|
||||||
|
prev_sp = this_base + info->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->base = d10v_make_daddr (this_base);
|
||||||
|
prev_sp = d10v_make_daddr (prev_sp);
|
||||||
|
|
||||||
|
/* Adjust all the saved registers so that they contain addresses and
|
||||||
|
not offsets. */
|
||||||
for (i = 0; i < NUM_REGS - 1; i++)
|
for (i = 0; i < NUM_REGS - 1; i++)
|
||||||
if (info->saved_regs[i])
|
if (info->saved_regs[i])
|
||||||
{
|
{
|
||||||
info->saved_regs[i] = fp - (info->sp_offset - info->saved_regs[i]);
|
info->saved_regs[i] = (prev_sp + info->saved_regs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->saved_regs[LR_REGNUM])
|
if (info->saved_regs[LR_REGNUM])
|
||||||
|
@ -803,20 +835,9 @@ d10v_frame_unwind_cache (struct frame_info *fi,
|
||||||
info->return_pc = d10v_make_iaddr (return_pc);
|
info->return_pc = d10v_make_iaddr (return_pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The SP is not normally (ever?) saved, but check anyway */
|
/* The SP_REGNUM is special. Instead of the address of the SP, the
|
||||||
if (!info->saved_regs[SP_REGNUM])
|
previous frame's SP value is saved. */
|
||||||
{
|
info->saved_regs[SP_REGNUM] = prev_sp;
|
||||||
/* if the FP was saved, that means the current FP is valid, */
|
|
||||||
/* otherwise, it isn't being used, so we use the SP instead */
|
|
||||||
if (info->uses_frame)
|
|
||||||
info->saved_regs[SP_REGNUM]
|
|
||||||
= d10v_read_fp () + info->size;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info->saved_regs[SP_REGNUM] = fp + info->size;
|
|
||||||
info->saved_regs[FP_REGNUM] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue