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
> aurel...@aurel32.net                 http://www.aurel32.net
> 
> 

--
John David Anglin       dave.ang...@bell.net


2016-09-11  John David Anglin  <dang...@gcc.gnu.org>

        * 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

Reply via email to