From dc1b0db2f27532adab873be588de5965c68cc23d Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Wed, 19 Jun 2002 01:12:07 +0000 Subject: [PATCH] * 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. --- gdb/alpha-tdep.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 4dc3e8e..564896f 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -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; -- 2.7.4