From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22669 invoked by alias); 22 Jun 2012 06:53:31 -0000 Received: (qmail 22658 invoked by uid 22791); 22 Jun 2012 06:53:29 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,FSL_RCVD_USER,KHOP_THREADED,MSGID_MULTIPLE_AT X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.155) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 22 Jun 2012 06:52:59 +0000 Received: from md13.u-strasbg.fr (md13.u-strasbg.fr [130.79.200.248]) by mailhost.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id q5M6qmnj021323 ; Fri, 22 Jun 2012 08:52:49 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from mailserver.u-strasbg.fr (ms12.u-strasbg.fr [130.79.204.112]) by md13.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id q5M6qlVa029374 ; Fri, 22 Jun 2012 08:52:48 +0200 (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from E6510Muller (lec67-4-82-230-53-140.fbx.proxad.net [82.230.53.140]) (user=mullerp mech=LOGIN) by mailserver.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id q5M6qkVS016947 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) ; Fri, 22 Jun 2012 08:52:47 +0200 (envelope-from pierre.muller@ics-cnrs.unistra.fr) From: "Pierre Muller" To: "'Maciej W. Rozycki'" Cc: "'GDB Patches'" References: <00a501cd495e$db6adea0$92409be0$@muller@ics-cnrs.unistra.fr> In-Reply-To: Subject: RE: [RFC] Fix MIPS frame prologue scan problem Date: Fri, 22 Jun 2012 06:53:00 -0000 Message-ID: <002a01cd5043$a0e9f310$e2bdd930$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable 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/msg00679.txt.bz2 > -----Message d'origine----- > De=A0: gdb-patches-owner@sourceware.org [mailto:gdb-patches- > owner@sourceware.org] De la part de Maciej W. Rozycki > Envoy=E9=A0: vendredi 22 juin 2012 01:12 > =C0=A0: Pierre Muller > Cc=A0: 'GDB Patches' > Objet=A0: Re: [RFC] Fix MIPS frame prologue scan problem >=20 > Hi Pierre, >=20 > Sorry about the delay, I've been swamped with stuff recently. Thanks for your reply. =20 > On Wed, 13 Jun 2012, Pierre Muller wrote: >=20 > > 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. >=20 > 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). I tried to read several MIPS documents, and the message was not that clear to me... =20 > 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: >=20 > "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. >=20 > 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." >=20 > 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). Our current problem is that we don't yet knoow the stacksize that we need for the function while we generate its code, so that using a frame pointer at previous value of stack pointer makes this really easier for now. > You need to adjust your code generated (BTW, note that the > convention assumed by the ABI is to use non-trapping arithmetic; I'm Is this the difference between ADDI and ADDIU? I thought it was only a signed/unsigned difference, Do that mean that you never generate any exception if you use the U version? I am really new to MIPS assembly... > assuming that you deliberately want to trap on overflows to detect the > stack pointer crossing the user/kernel segment boundary, right?). Not really as explained above ... =20 > 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. But my problem is really that GDB found my I do generate stabs debugging information, and give parameters and locals=20 offsets relative to frame pointer. But in mips32_scan_prologue, the first ADDI $s8,$sp,LocalSize instruction, interpreted it in mips32_scan_prologue function but ended up with a wrong position of my non-ABI standard frame pointer because it changed frame pointer register from sp to s8 register, but kept frame_offset value as set by the SUBI $sp, $sp, LocalSize=20 instruction analyzed before. Thus GDB wrongly ends up with a frame pointer located a value of $s8 register (as from ADDI instruction analysis) + LocalSize (from SUBI instruction) This means that of $sp is say at address addr $s8 is at addr +LocalSize and the virtual frame pointer=20 $fp at $s8 + LocalSize =3D addr + 2 * LocalSize This means that it would be better to remove analysis of the ADDI $s8, $sp, LocalSize than to leave the current behavior. I think that we should either use my proposed patch, or completely remove the analysis of this ADDI $s8, $sp, LocalSize... =20=20 =20 > I hope this helps, good luck with your port! >=20 > Maciej Thanks, Pierre