* 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:
parent
2736d49bb3
commit
dc1b0db2f2
1 changed files with 39 additions and 4 deletions
|
@ -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)
|
||||
{
|
||||
/* 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 */
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue