mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 20:43:45 +08:00
* 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:
parent
02e6ad56bf
commit
3b85b0f1a5
@ -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.
|
||||
|
134
gdb/avr-tdep.c
134
gdb/avr-tdep.c
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user