From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4985 invoked by alias); 21 Jun 2012 23:12:53 -0000 Received: (qmail 4971 invoked by uid 22791); 21 Jun 2012 23:12:51 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 21 Jun 2012 23:12:36 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1ShqYF-0005sr-Gz from Maciej_Rozycki@mentor.com ; Thu, 21 Jun 2012 16:12:35 -0700 Received: from SVR-IES-FEM-02.mgc.mentorg.com ([137.202.0.106]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 21 Jun 2012 16:12:35 -0700 Received: from [172.30.1.32] (137.202.0.76) by SVR-IES-FEM-02.mgc.mentorg.com (137.202.0.106) with Microsoft SMTP Server id 14.1.289.1; Fri, 22 Jun 2012 00:12:32 +0100 Date: Thu, 21 Jun 2012 23:12:00 -0000 From: "Maciej W. Rozycki" To: Pierre Muller CC: 'GDB Patches' Subject: Re: [RFC] Fix MIPS frame prologue scan problem In-Reply-To: <00a501cd495e$db6adea0$92409be0$@muller@ics-cnrs.unistra.fr> Message-ID: References: <00a501cd495e$db6adea0$92409be0$@muller@ics-cnrs.unistra.fr> User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-06/txt/msg00676.txt.bz2 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