* alpha-tdep.c (heuristic_proc_desc): Compute the size of the

current frame using only the first stack size adjustment. All
        subsequent size adjustments are not considered to be part of
        the "static" part of the current frame.
        Compute the address of the saved registers relative to the
        Frame Pointer ($fp) instead of the Stack Pointer if $fp is
        in use in this frame.
This commit is contained in:
Joel Brobecker 2002-06-19 01:12:07 +00:00
parent 2736d49bb3
commit dc1b0db2f2
1 changed files with 39 additions and 4 deletions

View File

@ -649,11 +649,13 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
struct frame_info *next_frame)
{
CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
CORE_ADDR vfp = sp;
CORE_ADDR cur_pc;
int frame_size;
int has_frame_reg = 0;
unsigned long reg_mask = 0;
int pcreg = -1;
int regno;
if (start_pc == 0)
return NULL;
@ -678,7 +680,12 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
{
if (word & 0x8000)
frame_size += (-word) & 0xffff;
{
/* Consider only the first stack allocation instruction
to contain the static size of the frame. */
if (frame_size == 0)
frame_size += (-word) & 0xffff;
}
else
/* Exit loop if a positive stack adjustment is found, which
usually means that the stack cleanup code in the function
@ -690,7 +697,16 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
{
int reg = (word & 0x03e00000) >> 21;
reg_mask |= 1 << reg;
temp_saved_regs[reg] = sp + (short) word;
/* Do not compute the address where the register was saved yet,
because we don't know yet if the offset will need to be
relative to $sp or $fp (we can not compute the address relative
to $sp if $sp is updated during the execution of the current
subroutine, for instance when doing some alloca). So just store
the offset for the moment, and compute the address later
when we know whether this frame has a frame pointer or not.
*/
temp_saved_regs[reg] = (short) word;
/* Starting with OSF/1-3.2C, the system libraries are shipped
without local symbols, but they still contain procedure
@ -719,8 +735,15 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
}
else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
pcreg = (word >> 16) & 0x1f;
else if (word == 0x47de040f) /* bis sp,sp fp */
has_frame_reg = 1;
else if (word == 0x47de040f || word == 0x47fe040f) /* bis sp,sp fp */
{
/* ??? I am not sure what instruction is 0x47fe040f, and I
am suspecting that there was a typo and should have been
0x47fe040f. I'm keeping it in the test above until further
investigation */
has_frame_reg = 1;
vfp = read_next_frame_reg (next_frame, ALPHA_GCC_FP_REGNUM);
}
}
if (pcreg == -1)
{
@ -759,6 +782,18 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
PROC_FRAME_REG (&temp_proc_desc) = ALPHA_GCC_FP_REGNUM;
else
PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
/* At this point, we know which of the Stack Pointer or the Frame Pointer
to use as the reference address to compute the saved registers address.
But in both cases, the processing above has set vfp to this reference
address, so just need to increment the offset of each saved register
by this address. */
for (regno = 0; regno < NUM_REGS; regno++)
{
if (reg_mask & 1 << regno)
temp_saved_regs[regno] += vfp;
}
PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
PROC_REG_MASK (&temp_proc_desc) = reg_mask;
PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? ALPHA_RA_REGNUM : pcreg;