* avr-tdep.c (avr_skip_prologue): Return PC unchanged if no prologue found.

(avr_frame_unwind_cache): Don't unwind FP for main.
Update a comment.
Save the computed prev_sp.
(avr_saved_regs_unwinder): Remove function.
(avr_frame_prev_register): Use PC unwind logic from
avr_saved_regs_unwinder, otherwise use trad_frame_prev_register.
This commit is contained in:
Theodore A. Roth 2003-07-16 23:20:51 +00:00
parent 02e6ad56bf
commit 3b85b0f1a5
2 changed files with 69 additions and 76 deletions

View File

@ -1,3 +1,14 @@
2003-07-16 Theodore A. Roth <troth@openavr.org>
* avr-tdep.c (avr_skip_prologue): Return PC unchanged if no prologue
found.
(avr_frame_unwind_cache): Don't unwind FP for main.
Update a comment.
Save the computed prev_sp.
(avr_saved_regs_unwinder): Remove function.
(avr_frame_prev_register): Use PC unwind logic from
avr_saved_regs_unwinder(), otherwise use trad_frame_prev_register().
2003-07-16 Andrew Cagney <cagney@redhat.com>
* frame-base.h (frame_base_p_ftype): Delete definition.

View File

@ -796,7 +796,9 @@ avr_skip_prologue (CORE_ADDR pc)
prologue_end = avr_scan_prologue (pc, &info);
if (info.prologue_type != AVR_PROLOGUE_NONE)
if (info.prologue_type == AVR_PROLOGUE_NONE)
return pc;
else
{
sal = find_pc_line (func_addr, 0);
@ -856,76 +858,6 @@ avr_extract_return_value (struct type *type, struct regcache *regcache,
}
}
static void
avr_saved_regs_unwinder (struct frame_info *next_frame,
struct trad_frame_saved_reg *this_saved_regs,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnump, void *bufferp)
{
if (this_saved_regs[regnum].addr != 0)
{
*optimizedp = 0;
*lvalp = lval_memory;
*addrp = this_saved_regs[regnum].addr;
*realnump = -1;
if (bufferp != NULL)
{
/* Read the value in from memory. */
if (regnum == AVR_PC_REGNUM)
{
/* Reading the return PC from the PC register is slightly
abnormal. register_size(AVR_PC_REGNUM) says it is 4 bytes,
but in reality, only two bytes (3 in upcoming mega256) are
stored on the stack.
Also, note that the value on the stack is an addr to a word
not a byte, so we will need to multiply it by two at some
point.
And to confuse matters even more, the return address stored
on the stack is in big endian byte order, even though most
everything else about the avr is little endian. Ick! */
/* FIXME: number of bytes read here will need updated for the
mega256 when it is available. */
ULONGEST pc;
unsigned char tmp;
unsigned char buf[2];
read_memory (this_saved_regs[regnum].addr, buf, 2);
/* Convert the PC read from memory as a big-endian to
little-endian order. */
tmp = buf[0];
buf[0] = buf[1];
buf[1] = tmp;
pc = (extract_unsigned_integer (buf, 2) * 2);
store_unsigned_integer (bufferp,
register_size (current_gdbarch, regnum),
pc);
}
else
{
read_memory (this_saved_regs[regnum].addr, bufferp,
register_size (current_gdbarch, regnum));
}
}
return;
}
/* No luck, assume this and the next frame have the same register
value. If a value is needed, pass the request on down the chain;
otherwise just return an indication that the value is in the same
register as the next frame. */
frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp,
realnump, bufferp);
}
/* Put here the code to store, into fi->saved_regs, the addresses of
the saved registers of frame described by FRAME_INFO. This
includes special registers such as pc and fp saved in special ways
@ -957,7 +889,8 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
if ((pc > 0) && (pc < frame_pc_unwind (next_frame)))
avr_scan_prologue (pc, info);
if (info->prologue_type != AVR_PROLOGUE_NONE)
if ((info->prologue_type != AVR_PROLOGUE_NONE)
&& (info->prologue_type != AVR_PROLOGUE_MAIN))
{
ULONGEST high_base; /* High byte of FP */
@ -987,8 +920,7 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
info->base = avr_make_saddr (this_base);
/* Adjust all the saved registers so that they contain addresses and not
offsets. We need to add one to the addresses since push ops are post
decrement on the avr. */
offsets. */
for (i = 0; i < NUM_REGS - 1; i++)
if (info->saved_regs[i].addr)
{
@ -1003,6 +935,10 @@ avr_frame_unwind_cache (struct frame_info *next_frame,
info->saved_regs[AVR_PC_REGNUM].addr = info->prev_sp;
}
/* The previous frame's SP needed to be computed. Save the computed
value. */
trad_frame_set_value (info->saved_regs, AVR_SP_REGNUM, info->prev_sp+1);
return info;
}
@ -1069,8 +1005,54 @@ avr_frame_prev_register (struct frame_info *next_frame,
struct avr_unwind_cache *info
= avr_frame_unwind_cache (next_frame, this_prologue_cache);
avr_saved_regs_unwinder (next_frame, info->saved_regs, regnum, optimizedp,
lvalp, addrp, realnump, bufferp);
if (regnum == AVR_PC_REGNUM)
{
if (trad_frame_addr_p (info->saved_regs, regnum))
{
*optimizedp = 0;
*lvalp = lval_memory;
*addrp = info->saved_regs[regnum].addr;
*realnump = -1;
if (bufferp != NULL)
{
/* Reading the return PC from the PC register is slightly
abnormal. register_size(AVR_PC_REGNUM) says it is 4 bytes,
but in reality, only two bytes (3 in upcoming mega256) are
stored on the stack.
Also, note that the value on the stack is an addr to a word
not a byte, so we will need to multiply it by two at some
point.
And to confuse matters even more, the return address stored
on the stack is in big endian byte order, even though most
everything else about the avr is little endian. Ick! */
/* FIXME: number of bytes read here will need updated for the
mega256 when it is available. */
ULONGEST pc;
unsigned char tmp;
unsigned char buf[2];
read_memory (info->saved_regs[regnum].addr, buf, 2);
/* Convert the PC read from memory as a big-endian to
little-endian order. */
tmp = buf[0];
buf[0] = buf[1];
buf[1] = tmp;
pc = (extract_unsigned_integer (buf, 2) * 2);
store_unsigned_integer (bufferp,
register_size (current_gdbarch, regnum),
pc);
}
}
}
else
trad_frame_prev_register (next_frame, info->saved_regs, regnum,
optimizedp, lvalp, addrp, realnump, bufferp);
}
static const struct frame_unwind avr_frame_unwind = {