This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Fix MIPS frame prologue scan problem


Hi Pierre,

 Sorry about the delay, I've been swamped with stuff recently.

On Wed, 13 Jun 2012, Pierre Muller wrote:

>   I am trying to extend the Free Pascal compiler to support
> MIPS architecture.
> 
>   From what I read so far, register $s8 (register number 30) can be used as
> a frame register,
> but when I set $s8 to the value of the stack pointer ($sp, register number
> 29)
> I get all my locals and parameter of functions wrong.
> 
>   I traced it down to the fact that GDB seems to use a
> 'virtual' frame pointer register called $fp,
> but which is miscalculated in my case.
> 
>   In GCC generated code, $s8 register gets the same value as
> $sp register, so that this problem does not show up in that case,
> but for me, if I have a prologue that reserves 80 bytes, 
> I will typically get 
> 
>   # Reserve 80 bytes for locals and area for called function parameters
>   addi $sp,$sp,-80
>   # Save $ra and $s8 registers, there could be others...
>   sw    $ra,44($sp)
>   sw   $s8,40($sp)
>   # Set $s8 to function entry value of $sp
>   addi $s8,$sp,80 
> 
>   Analysis of first instruction leads to setting of
> frame_offset to 80.
> 
>   The problem is that when the last instruction
> is analyzed by mips32_scan_prologue,
> it switches the frame_reg from $sp to $s8,
> but does not modify frame_offset value.
>   This leads to a frame pointer $fp
> being computed as $s8 + frame_offset
> which is equal to $sp + 2*frame_offset.
>   Thus all my locals are wrong :(
> 
>   Substraction of the constant in the last addi instruction (low_word)
> to frame_offset seems to cure my problem.

 Well, to put it short, you're not supposed to do that if you want to 
follow the MIPS ABI.  The MIPS processor has no hardware stack and the 
software implementation of the stack has been made such that there is 
generally no need to arrange for a hard frame pointer (in a register 
separate from the stack pointer), except where dynamic stack allocation 
is used (alloca in C terms).

 Therefore the right place to look for how the hard frame pointer has been 
specified is the "Dynamic Allocation of Stack Space" section in Chapter 3 
"Machine Interface" of the MIPS psABI document:

"When a function requires dynamically allocated stack space it manifests a 
frame pointer on entry to the function.  The frame pointer is kept in a 
callee-saved register so that it is not changed across subsequent function 
calls.  Dynamic stack allocation requires the following steps.

 1. On function entry, the function adjusts the stack pointer by the size
    of the static stack frame.  The frame pointer is then set to this 
    initial sp value and is used for referencing the static elements 
    within the stack frame, performing the normal function of the stack 
    pointer."

 So in fact both GCC and GDB are correct, you're not supposed to add a 
constant to the stack pointer when calculating the value of the frame 
pointer -- it is supposed to hold the value of the stack pointer *after* 
the frame has been allocated (in other words any frame offsets are 
non-negative).  You need to adjust your code generated (BTW, note that the 
convention assumed by the ABI is to use non-trapping arithmetic; I'm 
assuming that you deliberately want to trap on overflows to detect the 
stack pointer crossing the user/kernel segment boundary, right?).

 NB I suggest that you get real debug information generated as well; it 
can be stabs if DWARF-2 is too difficult to start with.  The heuristic 
unwinder is really the last-chance attempt made by GDB to find its way 
around, can only be relied on when applied to conservative code and is 
best avoided if possible.

 I hope this helps, good luck with your port!

  Maciej


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]