about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-07-31 17:27:38 -0700
committerUlrich Drepper <drepper@redhat.com>2009-07-31 17:27:38 -0700
commite4143e7a06455b073c41a6025fcd28fc5c134211 (patch)
treebd23efeb5b50bf01f164cb9c6759c917953a7a58
parent66ae9e50a336d87f943cc6314a0d405820fcdf8b (diff)
downloadglibc-e4143e7a06455b073c41a6025fcd28fc5c134211.tar.gz
glibc-e4143e7a06455b073c41a6025fcd28fc5c134211.tar.xz
glibc-e4143e7a06455b073c41a6025fcd28fc5c134211.zip
Optimize x86 and x86-64 ____longjmp_chk for Linux.
-rw-r--r--ChangeLog4
-rw-r--r--sysdeps/unix/sysv/linux/i386/____longjmp_chk.S73
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S94
3 files changed, 54 insertions, 117 deletions
diff --git a/ChangeLog b/ChangeLog
index fb046fe4c4..6d2a62b48c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2009-07-31  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Yet
+	another rewrite.  Much smaller and faster.
+	* sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: Likewise.
+
 	* sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Get
 	ss_flags from the correct location.
 
diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
index b07e972468..65c7bae9f2 100644
--- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S
@@ -58,8 +58,6 @@ ENTRY (____longjmp_chk)
 	PTR_DEMANGLE (%edx)
 	PTR_DEMANGLE (%edi)
 
-	pushl	$0
-	cfi_adjust_cfa_offset(4)
 	cmpl	%edi, %esp
 	jbe	.Lok
 
@@ -69,15 +67,25 @@ ENTRY (____longjmp_chk)
 	movl	%esp, %ecx
 	movl	$__NR_sigaltstack, %eax
 	ENTER_KERNEL
-	movl	4(%esp), %ebx
-	addl	$12, %esp
+	/* Without working sigaltstack we cannot perform the test.  */
+	test	%eax, %eax
+	jne	.Lok2
+	testl	$1, 4(%esp)
+	jz	.Lfail
+
+	movl	(%esp), %eax
+	addl	8(%esp), %eax
+	subl	%edi, %eax
+	cmpl	8(%esp), %eax
+	jae	.Lok2
+
+.Lfail:	CALL_FAIL
+
+.Lok2:	addl	$12, %esp
 	cfi_adjust_cfa_offset(-12)
-	movl	8(%esp), %ecx
-	testl	%eax, %eax
-	jne	.Lok
-	andl	$1, %ebx
-	movl	%ebx, (%esp)
-.Lok:
+	movl	4(%esp), %ecx
+
+.Lok:	/* We add unwind information for the target here.  */
 	cfi_def_cfa(%ecx, 0)
 	cfi_register(%eip, %edx)
 	cfi_register(%esp, %edi)
@@ -86,15 +94,11 @@ ENTRY (____longjmp_chk)
 	cfi_offset(%edi, JB_DI*4)
 	cfi_offset(%ebp, JB_BP*4)
 
-	movl	12(%esp), %eax	/* Second argument is return value.  */
-	xchgl	%edi, %esp
-	cfi_restore(%edi)
-
-	cmpl	%esp, %edi
-	jnbe	.Lcheck
+	movl	8(%esp), %eax	/* Second argument is return value.  */
+	movl	%edi, %esp
 
 	/* Restore registers.  */
-.Lout:	movl	(JB_BX*4)(%ecx), %ebx
+	movl	(JB_BX*4)(%ecx), %ebx
 	movl	(JB_SI*4)(%ecx), %esi
 	movl	(JB_DI*4)(%ecx), %edi
 	movl	(JB_BP*4)(%ecx), %ebp
@@ -105,39 +109,4 @@ ENTRY (____longjmp_chk)
 
 	/* Jump to saved PC.  */
 	jmp	*%edx
-
-	cfi_def_cfa(%ecx, 0)
-	cfi_register(%eip, %edx)
-	cfi_offset(%ebx, JB_BX*4)
-	cfi_offset(%esi, JB_SI*4)
-	cfi_offset(%edi, JB_DI*4)
-	cfi_offset(%ebp, JB_BP*4)
-
-.Lcheck:
-	cmpl	$0, (%edi)
-	je	.Lfail
-
-	subl	$12, %esp
-	cfi_adjust_cfa_offset(12)
-	xorl	%ebx, %ebx
-	movl	%esp, %ecx
-	movl	$__NR_sigaltstack, %eax
-	ENTER_KERNEL
-	testl	$1, 4(%esp)
-	leal	12(%esp), %esp
-	movl	8(%edi), %ecx
-	movl	12(%edi), %eax
-	cfi_adjust_cfa_offset(-12)
-	je	.Lout
-
-.Lfail:	xchgl	%edi, %esp
-	cfi_def_cfa(%esp, 8)
-	cfi_restore(%esp)
-	cfi_restore(%ebx)
-	cfi_restore(%esi)
-	cfi_undefined(%edi)
-	cfi_restore(%ebp)
-
-	CALL_FAIL
-	hlt
 END (____longjmp_chk)
diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
index 4e53ea63c9..87c728d03b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S
@@ -58,31 +58,36 @@ ENTRY(____longjmp_chk)
 	PTR_DEMANGLE (%rdx)
 #endif
 
+	cmpq	%r8, %rsp
+	jbe	.Lok
+
 	/* Save function parameters.  */
 	movq	%rdi, %r10
 	movl	%esi, %ecx
 
-	xorl	%eax, %eax
-	cmpq	%r8, %rsp
-	jbe	.Lok
-
-	subq	$24, %rsp
-	cfi_adjust_cfa_offset(24)
 	xorl	%edi, %edi
-	movq	%rsp, %rsi
+	leaq	-24(%rsp), %rsi
 	movl	$__NR_sigaltstack, %eax
 	syscall
+	/* Without working sigaltstack we cannot perform the test.  */
 	testl	%eax, %eax
-	movl	$0, %eax
-	leaq	24(%rsp), %rsp
-	cfi_adjust_cfa_offset(-24)
-	jne	.Lok
-	movl	-16(%rsp), %eax
-	andl	$1, %eax
+	jne	.Lok2
+	testl	$1, -16(%rsp)
+	jz	.Lfail
 
-.Lok:
-	/* We add unwind information for the target here.  */
-	cfi_def_cfa(%r10, 0)
+	movq	-24(%rsp), %rax
+	addq	-8(%rsp), %rax
+	subq	%r8, %rax
+	cmpq	-8(%rsp), %rax
+	jae	.Lok2
+
+.Lfail:	CALL_FAIL
+
+.Lok2:	movq	%r10, %rdi
+	movl	%ecx, %esi
+
+.Lok:	/* We add unwind information for the target here.  */
+	cfi_def_cfa(%rdi, 0)
 	cfi_register(%rsp,%r8)
 	cfi_register(%rbp,%r9)
 	cfi_register(%rip,%rdx)
@@ -91,55 +96,14 @@ ENTRY(____longjmp_chk)
 	cfi_offset(%r13,JB_R13*8)
 	cfi_offset(%r14,JB_R14*8)
 	cfi_offset(%r15,JB_R15*8)
-
-	xchgq	%r8, %rsp
-	cfi_restore(%rsp)
-	xchgq	%r9, %rbp
-	cfi_restore(%rbp)
-
-	movq	(JB_RBX*8)(%r10),%rbx
-	movq	(JB_R12*8)(%r10),%r12
-	movq	(JB_R13*8)(%r10),%r13
-	movq	(JB_R14*8)(%r10),%r14
-	movq	(JB_R15*8)(%r10),%r15
-
-	cmpq	%rsp, %r8
-	jnbe	.Lcheck
-
+	movq	(JB_RBX*8)(%rdi),%rbx
+	movq	(JB_R12*8)(%rdi),%r12
+	movq	(JB_R13*8)(%rdi),%r13
+	movq	(JB_R14*8)(%rdi),%r14
+	movq	(JB_R15*8)(%rdi),%r15
 	/* Set return value for setjmp.  */
-.Lout:	movl	%ecx, %eax
+	movl	%esi, %eax
+	movq	%r8,%rsp
+	movq	%r9,%rbp
 	jmpq	*%rdx
-
-.Lcheck:
-	testl	%eax, %eax
-	je	.Lfail
-
-	subq	$24, %rsp
-	cfi_adjust_cfa_offset(24)
-	xorl	%edi, %edi
-	movq	%rsp, %rsi
-	movl	$__NR_sigaltstack, %eax
-	syscall
-	addq	$24, %rsp
-	cfi_adjust_cfa_offset(-24)
-	testl	$1, -16(%rsp)
-	je	.Lout
-
-.Lfail:	xchgq	%r8, %rsp
-	/* We want the stack trace to show that of the caller.  */
-	cfi_def_cfa(%rsp, 8)
-	cfi_restore(%rsp)
-	cfi_register(%rbp, %r9)
-	cfi_restore(%rip)
-	cfi_restore(%rbx)
-	cfi_restore(%r12)
-	cfi_restore(%r13)
-	cfi_restore(%r14)
-	cfi_restore(%r15)
-
-	xchgq	%r9, %rbp
-	cfi_restore(%rbp)
-
-	CALL_FAIL
-	hlt
 END (BP_SYM (____longjmp_chk))