From patchwork Mon Sep 12 00:16:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John David Anglin X-Patchwork-Id: 15530 Received: (qmail 70412 invoked by alias); 12 Sep 2016 00:17:04 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 70366 invoked by uid 89); 12 Sep 2016 00:17:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.2 spammy=HMime-Version:framework, HMime-Version:Message, HMime-Version:Apple, recorded X-HELO: torfep02.bell.net Subject: [PATCH] hppa: Fix syscall cancellation Mime-Version: 1.0 (Apple Message framework v1085) From: John David Anglin In-Reply-To: <20160805222305.GA9571@aurel32.net> Date: Sun, 11 Sep 2016 20:16:50 -0400 Cc: SmartList porters , debian-glibc@lists.debian.org, GNU C Library , Helge Deller , Carlos O'Donell , Mike Frysinger Message-Id: <8F85756C-EF30-41B5-A42E-EA3B35145551@bell.net> References: <20160805222305.GA9571@aurel32.net> To: Aurelien Jarno X-Opwv-CommTouchExtSvcRefID: str=0001.0A020203.57D5F3F3.0041, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 The attached patch fixes syscall cancellation on hppa and the 2.24 regressions mentioned by Aurelien below. The problem was the forced unwind crashed in the syscall routine due to incorrect CFI offsets. The big problem was the stack offset was recorded as 64 after the stack pointer was bumped by 64. The new CFA offset should have been -64. Some register save offsets were also wrong and didn't reflect their correct position in the frame. I removed the cfi directives that previously recorded PIC register saves and restores, and the epilogue directives as these aren't needed by the unwinder. A test build is here: https://buildd.debian.org/status/fetch.php?pkg=glibc&arch=hppa&ver=2.24-2%2Bb1&stamp=1473631746 As can be seen, the cancellation tests now all pass. Please install if okay. Thanks, Dave Anglin PS: The nptl/tst-default-attr, rt/tst-timer4 and rt/tst-timer5 fails were addressed in a separate patch. On 2016-08-05, at 6:23 PM, Aurelien Jarno wrote: > Dear HPPA porters, > > We would like to push glibc 2.24 currently in experimental into sid in > the next weeks. It is going to be the version we ship in Stretch. > > I have looked at the testsuite results from the latest uploads, there > are 9 real regressions (ie not new tests) mostly related to NPTL: > > * FAIL: nptl/tst-default-attr > original exit status 22 > stacksize test > guardsize test > sched test > tst-default-attr.c:101: pthread_create returned 22 (errno = 22) > tst-default-attr.c:371: do_sched_test returned 22 (errno = 22) > > The test hasn't changed recently. > > > * FAIL: rt/tst-timer4 > original exit status 1 > clock_gettime returned timespec = { 1469505650, 981046459 } > clock_getres returned timespec = { 0, 4000000 } > Timed out: killed the child process > > * FAIL: rt/tst-timer5 > original exit status 1 > clock_gettime returned timespec = { 1665713, 650390357 } > clock_getres returned timespec = { 0, 4000000 } > Timed out: killed the child process > > The above two seems related. > > > * FAIL: nptl/tst-cancel-self > original exit status 1 > Didn't expect signal from child: got `Segmentation fault' > > * FAIL: nptl/tst-cancel-self-cancelstate > original exit status 1 > Didn't expect signal from child: got `Segmentation fault' > > * FAIL: nptl/tst-cancel12 > original exit status 1 > Didn't expect signal from child: got `Segmentation fault' > > * FAIL: nptl/tst-cancel14 > original exit status 1 > Didn't expect signal from child: got `Segmentation fault' > > * FAIL: nptl/tst-cancelx12 > original exit status 1 > Didn't expect signal from child: got `Segmentation fault' > > * FAIL: nptl/tst-cancelx14 > original exit status 1 > Didn't expect signal from child: got `Segmentation fault' > > The above 6 failures appeared when switching from GCC 5 to GCC 6 and > looks like quite worrisome. > > > Given that GCC 5 is going to be removed soon, we have to build the GNU > libc with GCC 6. Could you please have a look at the issues? > > Thanks, > Aurelien > > -- > Aurelien Jarno GPG: 4096R/1DDD8C9B > aurelien@aurel32.net http://www.aurel32.net > > --- John David Anglin dave.anglin@bell.net 2016-09-11 John David Anglin * sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h (PSEUDO): Fix CFA offset. Use .cfi_def_cfa_offset instead of .cfi_offset. Don't record stack pointer offset. Correct PIC register offset. Don't mention frame related instructions in epilogue. (PUSHARGS_1): Correct offset. (PUSHARGS_2): Likewise. (PUSHARGS_3): Likewise. (PUSHARGS_4): Likewise. (PUSHARGS_5): Likewise. (PUSHARGS_6): Likewise. (POPARGS_1): Don't mention register restore. (POPARGS_2): Likewise. (POPARGS_3): Likewise. (POPARGS_4): Likewise. (POPARGS_5): Likewise. (POPARGS_6): Likewise. * sysdeps/unix/sysv/linux/hppa/sysdep.h (SAVE_PIC): Don't mention copy of PIC register. (LOAD_PIC): Likewise don't mention restore. (DO_CALL): Fix CFA offset. Use .cfi_def_cfa_offset instead of .cfi_offset. Don't record stack pointer offset. Correct PIC register offset. Don't mention frame related instructions in epilogue. diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h b/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h index cafc752..f239408 100644 --- a/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h +++ b/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h @@ -62,12 +62,11 @@ ENTRY (__##syscall_name##_nocancel) \ DOARGS_##args ASM_LINE_SEP \ stwm TREG, 64(%sp) ASM_LINE_SEP \ + .cfi_def_cfa_offset -64 ASM_LINE_SEP \ .cfi_offset TREG, 0 ASM_LINE_SEP \ - .cfi_adjust_cfa_offset 64 ASM_LINE_SEP \ stw %sp, -4(%sp) ASM_LINE_SEP \ - .cfi_offset 30, -4 ASM_LINE_SEP \ stw %r19, -32(%sp) ASM_LINE_SEP \ - .cfi_offset 19, -32 ASM_LINE_SEP \ + .cfi_offset 19, 32 ASM_LINE_SEP \ /* Save r19 */ ASM_LINE_SEP \ SAVE_PIC(TREG) ASM_LINE_SEP \ /* Do syscall, delay loads # */ ASM_LINE_SEP \ @@ -91,21 +90,19 @@ L(pre_nc_end): ASM_LINE_SEP \ /* No need to LOAD_PIC */ ASM_LINE_SEP \ /* Undo frame */ ASM_LINE_SEP \ ldwm -64(%sp),TREG ASM_LINE_SEP \ - .cfi_adjust_cfa_offset -64 ASM_LINE_SEP \ /* Restore rp before exit */ ASM_LINE_SEP \ ldw -20(%sp), %rp ASM_LINE_SEP \ - .cfi_restore 2 ASM_LINE_SEP \ ret ASM_LINE_SEP \ END(__##syscall_name##_nocancel) ASM_LINE_SEP \ /**********************************************/ASM_LINE_SEP \ ENTRY (name) \ DOARGS_##args ASM_LINE_SEP \ stwm TREG, 64(%sp) ASM_LINE_SEP \ - .cfi_adjust_cfa_offset 64 ASM_LINE_SEP \ + .cfi_def_cfa_offset -64 ASM_LINE_SEP \ + .cfi_offset TREG, 0 ASM_LINE_SEP \ stw %sp, -4(%sp) ASM_LINE_SEP \ - .cfi_offset 30, -4 ASM_LINE_SEP \ stw %r19, -32(%sp) ASM_LINE_SEP \ - .cfi_offset 19, -32 ASM_LINE_SEP \ + .cfi_offset 19, 32 ASM_LINE_SEP \ /* Done setting up frame, continue... */ ASM_LINE_SEP \ SINGLE_THREAD_P ASM_LINE_SEP \ cmpib,<>,n 0,%ret0,L(pseudo_cancel) ASM_LINE_SEP \ @@ -168,40 +165,32 @@ L(pre_end): ASM_LINE_SEP \ /* No need to LOAD_PIC */ ASM_LINE_SEP \ /* Undo frame */ ASM_LINE_SEP \ ldwm -64(%sp),TREG ASM_LINE_SEP \ - .cfi_adjust_cfa_offset -64 ASM_LINE_SEP \ /* Restore rp before exit */ ASM_LINE_SEP \ - ldw -20(%sp), %rp ASM_LINE_SEP \ - .cfi_restore 2 ASM_LINE_SEP + ldw -20(%sp), %rp ASM_LINE_SEP /* Save arguments into our frame */ # define PUSHARGS_0 /* nothing to do */ # define PUSHARGS_1 PUSHARGS_0 stw %r26, -36(%sr0,%sp) ASM_LINE_SEP \ - .cfi_offset 26, -36 ASM_LINE_SEP + .cfi_offset 26, 28 ASM_LINE_SEP # define PUSHARGS_2 PUSHARGS_1 stw %r25, -40(%sr0,%sp) ASM_LINE_SEP \ - .cfi_offset 25, -40 ASM_LINE_SEP + .cfi_offset 25, 24 ASM_LINE_SEP # define PUSHARGS_3 PUSHARGS_2 stw %r24, -44(%sr0,%sp) ASM_LINE_SEP \ - .cfi_offset 24, -44 ASM_LINE_SEP + .cfi_offset 24, 20 ASM_LINE_SEP # define PUSHARGS_4 PUSHARGS_3 stw %r23, -48(%sr0,%sp) ASM_LINE_SEP \ - .cfi_offset 23, -48 ASM_LINE_SEP + .cfi_offset 23, 16 ASM_LINE_SEP # define PUSHARGS_5 PUSHARGS_4 stw %r22, -52(%sr0,%sp) ASM_LINE_SEP \ - .cfi_offset 22, -52 ASM_LINE_SEP + .cfi_offset 22, 12 ASM_LINE_SEP # define PUSHARGS_6 PUSHARGS_5 stw %r21, -56(%sr0,%sp) ASM_LINE_SEP \ - .cfi_offset 21, -56 ASM_LINE_SEP + .cfi_offset 21, 8 ASM_LINE_SEP /* Bring them back from the stack */ # define POPARGS_0 /* nothing to do */ -# define POPARGS_1 POPARGS_0 ldw -36(%sr0,%sp), %r26 ASM_LINE_SEP \ - .cfi_restore 26 ASM_LINE_SEP -# define POPARGS_2 POPARGS_1 ldw -40(%sr0,%sp), %r25 ASM_LINE_SEP \ - .cfi_restore 25 ASM_LINE_SEP -# define POPARGS_3 POPARGS_2 ldw -44(%sr0,%sp), %r24 ASM_LINE_SEP \ - .cfi_restore 24 ASM_LINE_SEP -# define POPARGS_4 POPARGS_3 ldw -48(%sr0,%sp), %r23 ASM_LINE_SEP \ - .cfi_restore 23 ASM_LINE_SEP -# define POPARGS_5 POPARGS_4 ldw -52(%sr0,%sp), %r22 ASM_LINE_SEP \ - .cfi_restore 22 ASM_LINE_SEP -# define POPARGS_6 POPARGS_5 ldw -56(%sr0,%sp), %r21 ASM_LINE_SEP \ - .cfi_restore 21 ASM_LINE_SEP +# define POPARGS_1 POPARGS_0 ldw -36(%sr0,%sp), %r26 ASM_LINE_SEP +# define POPARGS_2 POPARGS_1 ldw -40(%sr0,%sp), %r25 ASM_LINE_SEP +# define POPARGS_3 POPARGS_2 ldw -44(%sr0,%sp), %r24 ASM_LINE_SEP +# define POPARGS_4 POPARGS_3 ldw -48(%sr0,%sp), %r23 ASM_LINE_SEP +# define POPARGS_5 POPARGS_4 ldw -52(%sr0,%sp), %r22 ASM_LINE_SEP +# define POPARGS_6 POPARGS_5 ldw -56(%sr0,%sp), %r21 ASM_LINE_SEP # if IS_IN (libpthread) # ifdef PIC diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep.h b/sysdeps/unix/sysv/linux/hppa/sysdep.h index b459f0a..00cb366 100644 --- a/sysdeps/unix/sysv/linux/hppa/sysdep.h +++ b/sysdeps/unix/sysv/linux/hppa/sysdep.h @@ -49,11 +49,9 @@ to another function */ #define TREG 4 #define SAVE_PIC(SREG) \ - copy %r19, SREG ASM_LINE_SEP \ - .cfi_register 19, SREG + copy %r19, SREG #define LOAD_PIC(LREG) \ - copy LREG , %r19 ASM_LINE_SEP \ - .cfi_restore 19 + copy LREG , %r19 /* Inline assembly defines */ #define TREG_ASM "%r4" /* Cant clobber r3, it holds framemarker */ #define SAVE_ASM_PIC " copy %%r19, %" TREG_ASM "\n" @@ -292,12 +290,11 @@ #define DO_CALL(syscall_name, args) \ /* Create a frame */ ASM_LINE_SEP \ stwm TREG, 64(%sp) ASM_LINE_SEP \ + .cfi_def_cfa_offset -64 ASM_LINE_SEP \ .cfi_offset TREG, 0 ASM_LINE_SEP \ - .cfi_adjust_cfa_offset 64 ASM_LINE_SEP \ stw %sp, -4(%sp) ASM_LINE_SEP \ - .cfi_offset 30, -4 ASM_LINE_SEP \ stw %r19, -32(%sp) ASM_LINE_SEP \ - .cfi_offset 19, -32 ASM_LINE_SEP \ + .cfi_offset 19, 32 ASM_LINE_SEP \ /* Save r19 */ ASM_LINE_SEP \ SAVE_PIC(TREG) ASM_LINE_SEP \ /* Do syscall, delay loads # */ ASM_LINE_SEP \ @@ -320,10 +317,8 @@ L(pre_end): ASM_LINE_SEP \ /* Restore our frame, restoring TREG */ ASM_LINE_SEP \ ldwm -64(%sp), TREG ASM_LINE_SEP \ - .cfi_adjust_cfa_offset -64 ASM_LINE_SEP \ /* Restore return pointer */ ASM_LINE_SEP \ - ldw -20(%sp),%rp ASM_LINE_SEP \ - .cfi_restore 2 ASM_LINE_SEP + ldw -20(%sp),%rp ASM_LINE_SEP /* We do nothing with the return, except hand it back to someone else */ #undef DO_CALL_NOERRNO