From 66ae9e50a336d87f943cc6314a0d405820fcdf8b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 12:57:45 -0700 Subject: [PATCH 1/2] Fix ____longjmp_chk on x86-64. After a recent change to fix CFI in ____longjmp_chk the test of the ss_flags used the wrong memory location. --- ChangeLog | 5 +++++ sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8759b2c08d..fb046fe4c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-07-31 Ulrich Drepper + + * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Get + ss_flags from the correct location. + 2009-07-31 H.J. Lu * sysdeps/i386/i686/Makefile (sysdep_routines): Add cacheinfo. diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S index 80e4aff36d..4e53ea63c9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -77,7 +77,7 @@ ENTRY(____longjmp_chk) leaq 24(%rsp), %rsp cfi_adjust_cfa_offset(-24) jne .Lok - movl 8(%rsp), %eax + movl -16(%rsp), %eax andl $1, %eax .Lok: @@ -122,7 +122,7 @@ ENTRY(____longjmp_chk) syscall addq $24, %rsp cfi_adjust_cfa_offset(-24) - testl $1, 8(%rsp) + testl $1, -16(%rsp) je .Lout .Lfail: xchgq %r8, %rsp From e4143e7a06455b073c41a6025fcd28fc5c134211 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 17:27:38 -0700 Subject: [PATCH 2/2] Optimize x86 and x86-64 ____longjmp_chk for Linux. --- ChangeLog | 4 + .../unix/sysv/linux/i386/____longjmp_chk.S | 73 +++++--------- .../unix/sysv/linux/x86_64/____longjmp_chk.S | 94 ++++++------------- 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 + * 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))