From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27677 invoked by alias); 6 Mar 2008 22:13:11 -0000 Received: (qmail 27664 invoked by uid 22791); 6 Mar 2008 22:13:09 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 06 Mar 2008 22:12:52 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m26MCoXR007696 for ; Thu, 6 Mar 2008 17:12:50 -0500 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m26MCo5W027013 for ; Thu, 6 Mar 2008 17:12:50 -0500 Received: from ironwood.lan (vpn-14-33.rdu.redhat.com [10.11.14.33]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m26MCnni000664 for ; Thu, 6 Mar 2008 17:12:50 -0500 Date: Thu, 06 Mar 2008 22:13:00 -0000 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: [RFC] mips-tdep.c: Ignore use of sw after sd in prologue scanner Message-ID: <20080306151249.122b91d3@ironwood.lan> X-Mailer: Claws Mail 3.3.1 (GTK+ 2.12.5; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-IsSubscribed: yes 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: 2008-03/txt/msg00043.txt.bz2 While running the GDB testsuite on a mips64 target, we were encountering a large number of failures in gdb.base/restore.exp. The simulator was dying with the message UNPREDICTABLE: PC = some-address It turned out that GDB was incorrectly restoring some of the registers when using GDB's "return" command. The prologue scanner was the root cause of the problem. Consider the following example: 0x80020310 : sd ra,16(sp) 0x80020314 : sd s8,8(sp) 0x80020318 : move s8,sp 0x8002031c : move v0,a0 0x80020320 : sll v0,v0,0x0 0x80020324 : sw v0,0(s8) While examining that prologue, the scanner was recording the offsets for ra and s8 as it should, but it was also recording an offset for v0. Note that when saving ra and s8, the compiler uses sd instructions since this is a 64-bit architecture, but when saving v0 (which is an argument to the function), it uses an sw instruction. The value of 0x7eec was being passed to callee1. When the return was forced, this value was restored to the high 32 bits of v0. When, later on, the simulator executed a move instruction involving v0, it checked to make sure that the high 32 bits were in a reasonable state (all 0s or all 1s). If not (and it wasn't) it would abort execution with that "UNPREDICTABLE" message. The patch below fixes the problem by setting a flag when an "sd" instruction is seen. When this flag is set, patterns involving "sw" which save a register to the stack are ignored. Comments? * mips-tdep.c (mips32_scan_prologue): After seeing an "sd" instruction, don't allow patterns involving the "sw" instruction to be used for recording the offset at which a register has been saved on the stack. Index: mips-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-tdep.c,v retrieving revision 1.469 diff -u -p -r1.469 mips-tdep.c --- mips-tdep.c 20 Feb 2008 14:34:43 -0000 1.469 +++ mips-tdep.c 6 Mar 2008 21:59:01 -0000 @@ -1929,6 +1929,7 @@ mips32_scan_prologue (CORE_ADDR start_pc CORE_ADDR end_prologue_addr = 0; int seen_sp_adjust = 0; + int seen_sd = 0; int load_immediate_bytes = 0; struct gdbarch *gdbarch = get_frame_arch (next_frame); @@ -1973,7 +1974,7 @@ restart: break; seen_sp_adjust = 1; } - else if ((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */ + else if (((high_word & 0xFFE0) == 0xafa0) && !seen_sd) /* sw reg,offset($sp) */ { set_reg_offset (this_cache, reg, sp + low_word); } @@ -1981,6 +1982,8 @@ restart: { /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra. */ set_reg_offset (this_cache, reg, sp + low_word); + /* If sd is used, don't consider later sw instructions. */ + seen_sd = 1; } else if (high_word == 0x27be) /* addiu $30,$sp,size */ { @@ -2041,7 +2044,7 @@ restart: } } } - else if ((high_word & 0xFFE0) == 0xafc0) /* sw reg,offset($30) */ + else if ((high_word & 0xFFE0) == 0xafc0 && !seen_sd) /* sw reg,offset($30) */ { set_reg_offset (this_cache, reg, frame_addr + low_word); }