From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 630 invoked by alias); 7 Dec 2010 20:28:17 -0000 Received: (qmail 616 invoked by uid 22791); 7 Dec 2010 20:28:16 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_EG,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 07 Dec 2010 20:28:09 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oB7KS7ND027522 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 7 Dec 2010 15:28:07 -0500 Received: from mesquite.lan ([10.3.113.8]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oB7KS6He016575 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Tue, 7 Dec 2010 15:28:07 -0500 Date: Tue, 07 Dec 2010 20:28:00 -0000 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: [RFC] mips-tdep.c: Sign extend values placed into registers for inferior function calls Message-ID: <20101207132806.67a0baa2@mesquite.lan> 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: 2010-12/txt/msg00074.txt.bz2 The patch below fixes a significant number of failures for mips64 targets running in 32-bit mode. In recent testing of mipsisa64-elf with the target_board set to mips-sim-idt64/-EB/-mips32, I saw 529 fewer failures, though, admittedly, many of these are cascade failures. Here is an example, taken from the log file, of one failure fixed by this patch: p t_short_values(10,-23) UNPREDICTABLE: PC = 0x800209d4 Quit (gdb) FAIL: gdb.base/callfuncs.exp: p t_short_values(10,-23) In creating the inferior function call, gdb is placing a negative value, -23, sign extended only to 32-bits, into one of the 64-bit argument registers. When the simulator executes a move instruction in the course of executing t_short_values(), it first checks to make sure that the register value is correctly sign extended. I.e. it looks at bits 32-63 and makes sure that they all match the value in bit 31. If it's not correctly sign extended, it outputs the "UNPREDICTABLE" message. It then aborts back to GDB, often causing further problems for later tests. The following tests are all affected by this bug. (There are many other failures too, but most are due to GDB attempting to perform the requested operation while it still thinks the target is running.) Note that some of these tests are listed as PASS. There's still a problem though. Subsequent tests fail due to the abort caused due to the incorrect sign extension. FAIL: gdb.base/call-ar-st.exp: print sum_array_print(10, *list1, *list2, *list3, *list4) FAIL: gdb.base/call-rt-st.exp: print print_struct_rep(*struct1) FAIL: gdb.base/callfuncs.exp: p t_short_values(10,-23) PASS: gdb.base/structs.exp: call Fun(foo); call 5 structs-tc PASS: gdb.base/structs.exp: call Fun(foo); call 3 structs-ts PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-ti PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tl PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tll PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tf PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-td PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tld PASS: gdb.base/structs.exp: call Fun(foo); call 4 structs-ts-tc PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-ti-tc PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tl-tc PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tll-tc PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tf-tc PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-td-tc PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tld-tc PASS: gdb.base/structs.exp: call Fun(foo); call 3 structs-tc-ts PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tc-ti PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tc-tl PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tc-tll PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tc-tf PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tc-td PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tc-tld PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-td-tf PASS: gdb.base/structs.exp: call Fun(foo); call 2 structs-tf-td FAIL: gdb.cp/classes.exp: call class_param.Aval_a (g_A) FAIL: gdb.cp/virtfunc.exp: print pDe->vg() I think the patch below is almost obvious. We all know by now that mips values usually need to be sign extended. I should note too that there are several other instances in mips-tdep.c where unsigned operations are still performed. I'll address some of those problems in other patches soon to be posted, but only for those cases where I can demonstrate that a failure is fixed as a result. Comments? Kevin * mips-tdep.c (mips_eabi_push_dummy_call): Place signed, rather than unsigned, values in registers. Index: mips-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-tdep.c,v retrieving revision 1.508 diff -u -p -r1.508 mips-tdep.c --- mips-tdep.c 28 Nov 2010 04:31:24 -0000 1.508 +++ mips-tdep.c 7 Dec 2010 19:52:14 -0000 @@ -2755,7 +2755,7 @@ mips_eabi_push_dummy_call (struct gdbarc fprintf_unfiltered (gdb_stdlog, "mips_eabi_push_dummy_call: struct_return reg=%d %s\n", argreg, paddress (gdbarch, struct_addr)); - regcache_cooked_write_unsigned (regcache, argreg++, struct_addr); + regcache_cooked_write_signed (regcache, argreg++, struct_addr); } /* Now load as many as possible of the first arguments into @@ -2834,7 +2834,7 @@ mips_eabi_push_dummy_call (struct gdbarc if (mips_debug) fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", float_argreg, phex (regval, 4)); - regcache_cooked_write_unsigned (regcache, float_argreg++, regval); + regcache_cooked_write_signed (regcache, float_argreg++, regval); /* Write the high word of the double to the odd register(s). */ regval = extract_unsigned_integer (val + 4 - low_offset, @@ -2842,7 +2842,7 @@ mips_eabi_push_dummy_call (struct gdbarc if (mips_debug) fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", float_argreg, phex (regval, 4)); - regcache_cooked_write_unsigned (regcache, float_argreg++, regval); + regcache_cooked_write_signed (regcache, float_argreg++, regval); } else { @@ -2854,7 +2854,7 @@ mips_eabi_push_dummy_call (struct gdbarc if (mips_debug) fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s", float_argreg, phex (regval, len)); - regcache_cooked_write_unsigned (regcache, float_argreg++, regval); + regcache_cooked_write_signed (regcache, float_argreg++, regval); } } else @@ -2937,13 +2937,13 @@ mips_eabi_push_dummy_call (struct gdbarc && !fp_register_arg_p (gdbarch, typecode, arg_type)) { LONGEST regval = - extract_unsigned_integer (val, partial_len, byte_order); + extract_signed_integer (val, partial_len, byte_order); if (mips_debug) fprintf_filtered (gdb_stdlog, " - reg=%d val=%s", argreg, phex (regval, regsize)); - regcache_cooked_write_unsigned (regcache, argreg, regval); + regcache_cooked_write_signed (regcache, argreg, regval); argreg++; }