diff mbox

hppa: Fix syscall cancellation

Message ID 8F85756C-EF30-41B5-A42E-EA3B35145551@bell.net
State New
Headers show

Commit Message

John David Anglin Sept. 12, 2016, 12:16 a.m. UTC
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  <danglin@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 mbox

Patch

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