From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19201 invoked by alias); 7 Oct 2010 00:14:05 -0000 Received: (qmail 19174 invoked by uid 22791); 7 Oct 2010 00:13:55 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,TW_FD,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from anubis.se.axis.com (HELO anubis.se.axis.com) (195.60.68.12) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 07 Oct 2010 00:13:47 +0000 Received: from localhost (localhost [127.0.0.1]) by anubis.se.axis.com (Postfix) with ESMTP id EB84519D21 for ; Thu, 7 Oct 2010 02:13:44 +0200 (CEST) Received: from anubis.se.axis.com ([127.0.0.1]) by localhost (anubis.se.axis.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id SVU+iFo62j2x for ; Thu, 7 Oct 2010 02:13:43 +0200 (CEST) Received: from krynn.se.axis.com (krynn.se.axis.com [10.0.2.170]) by anubis.se.axis.com (Postfix) with ESMTPS id D94A719D18 for ; Thu, 7 Oct 2010 02:13:43 +0200 (CEST) Received: from ignucius.se.axis.com (ignucius.se.axis.com [10.88.21.50]) by krynn.se.axis.com (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id o970DhL1015496; Thu, 7 Oct 2010 02:13:43 +0200 Received: from ignucius.se.axis.com (localhost [127.0.0.1]) by ignucius.se.axis.com (8.12.8p1/8.12.8/Debian-2woody1) with ESMTP id o970DhF6026313; Thu, 7 Oct 2010 02:13:43 +0200 Received: (from hp@localhost) by ignucius.se.axis.com (8.12.8p1/8.12.8/Debian-2woody1) id o970DhGm026309; Thu, 7 Oct 2010 02:13:43 +0200 Date: Thu, 07 Oct 2010 00:14:00 -0000 Message-Id: <201010070013.o970DhGm026309@ignucius.se.axis.com> From: Hans-Peter Nilsson To: gdb-patches@sourceware.org Subject: Committed: fix two simulator lseek syscall bugs (sim/cris and generic) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT 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-10/txt/msg00106.txt.bz2 These were noticed while investigating , a libstdc++ testsuite regression, in which my autotester using the simulator flagged a regression, a proper libstdc++ bug, but somewhat serendipitously for the wrong reason; these bugs. The lseek syscall is a gotcha. That bug might be there for other ports (and I wouldn't be surprised if in other simulators). The src/sim API to the host (struct cb_syscall) uses "long" for syscall parameters. The cris-*-* target is ILP32, and target syscall parameters, generally being unsigned 32-bit numbers and addresses are handled in the port as "USI" (uint32_t). But, the lseek position parameter needs to be sign-extended rather than zero-extended when on a LP64 host, or you'll end up with 4G files (thankfully sparse) for writable files, and wrong positions or errors for other files. I couldn't think of any other syscall parameter requiring sign-extension for this target. Speaking of lseek errors, the callback for lseek didn't handle them. Just a matter of wrapping it using the correct idiom, like for other nearby I/O calls. Regression-tested for cris-elf, committed. sim/testsuite: * sim/cris/c/seek3.c, sim/cris/c/seek4.c: New tests. sim/cris: * traps.c (cris_break_13_handler): Pass lseek offset parameter as sign-extended. sim/common: * callback.c (os_lseek): Call wrap on lseek result. Index: sim/cris/traps.c =================================================================== RCS file: /cvs/src/src/sim/cris/traps.c,v retrieving revision 1.22 diff -u -p -r1.22 traps.c --- sim/cris/traps.c 14 Jan 2009 10:53:06 -0000 1.22 +++ sim/cris/traps.c 6 Oct 2010 05:06:01 -0000 @@ -1477,6 +1477,14 @@ cris_break_13_handler (SIM_CPU *current_ s.arg2 = arg2; s.arg3 = arg3; + /* The type of s.arg2 is long, so for hosts with 64-bit longs, we need + to sign-extend the lseek offset to be passed as a signed number, + else we'll truncate it to something > 2GB on hosts where sizeof + long > sizeof USI. We avoid doing it for all syscalls, as arg2 is + e.g. an address for some syscalls. */ + if (callnum == TARGET_SYS_lseek) + s.arg2 = (SI) arg2; + if (callnum == TARGET_SYS_exit_group || (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0)) { Index: sim/common/callback.c =================================================================== RCS file: /cvs/src/src/sim/common/callback.c,v retrieving revision 1.25 diff -u -p -r1.25 callback.c --- sim/common/callback.c 14 Jan 2009 10:53:05 -0000 1.25 +++ sim/common/callback.c 6 Oct 2010 05:06:01 -0000 @@ -278,7 +278,7 @@ os_lseek (p, fd, off, way) result = fdbad (p, fd); if (result) return result; - result = lseek (fdmap (p, fd), off, way); + result = wrap (p, lseek (fdmap (p, fd), off, way)); return result; } --- /dev/null Tue Oct 29 15:57:07 2002 +++ sim/testsuite/sim/cris/c/seek3.c Wed Oct 6 00:53:22 2010 @@ -0,0 +1,49 @@ +/* Check for a sim bug, whereby the position was always unsigned + (truncation instead of sign-extension for 64-bit hosts). */ +#include +#include +#include +#include +#include +#include +#include + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt[] + = "A random line of text, used to test correct read, write and seek.\n"; + char buf[sizeof tsttxt] = ""; + const char correct[] = "correct"; + char buf2[sizeof correct] = {0}; + int fd; + + f = fopen (fname, "wb"); + if (f == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), f) != strlen (tsttxt) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + /* We have to use file-descriptor calls instead of stream calls to + provoke the bug (for stream calls, the lseek call is canonicalized + to use SEEK_SET). */ + fd = open (fname, O_RDONLY); + if (fd < 0 + || read (fd, buf, strlen (tsttxt)) != strlen (tsttxt) + || strcmp (buf, tsttxt) != 0 + || lseek (fd, -30L, SEEK_CUR) != 36 + || read (fd, buf2, strlen (correct)) != strlen (correct) + || strcmp (buf2, correct) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} --- /dev/null Tue Oct 29 15:57:07 2002 +++ sim/testsuite/sim/cris/c/seek4.c Wed Oct 6 00:56:53 2010 @@ -0,0 +1,44 @@ +/* Check for a sim bug, whereby an invalid seek (to a negative offset) + did not return an error. */ +#include +#include +#include +#include +#include +#include +#include +#include + +int +main (void) +{ + FILE *f; + const char fname[] = "sk1test.dat"; + const char tsttxt[] + = "A random line of text, used to test correct read, write and seek.\n"; + char buf[sizeof tsttxt] = ""; + int fd; + + f = fopen (fname, "wb"); + if (f == NULL + || fwrite (tsttxt, 1, strlen (tsttxt), f) != strlen (tsttxt) + || fclose (f) != 0) + { + printf ("fail\n"); + exit (1); + } + + fd = open (fname, O_RDONLY); + if (fd < 0 + || lseek (fd, -1L, SEEK_CUR) != -1 + || errno != EINVAL + || read (fd, buf, strlen (tsttxt)) != strlen (tsttxt) + || strcmp (buf, tsttxt) != 0) + { + printf ("fail\n"); + exit (1); + } + + printf ("pass\n"); + exit (0); +} brgds, H-P