Fix x86-64 ____longjmp_chk to handle signal stacks.
authorUlrich Drepper <drepper@redhat.com>
Fri, 31 Jul 2009 00:31:48 +0000 (17:31 -0700)
committerUlrich Drepper <drepper@redhat.com>
Fri, 31 Jul 2009 00:31:48 +0000 (17:31 -0700)
The simple test previously used might trigger if the longjmp jumps
from the signal stack to the normal stack.  We now explicitly test
for this case.

ChangeLog
sysdeps/x86_64/____longjmp_chk.S
sysdeps/x86_64/__longjmp.S

index 9e78199..2492d49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-07-30  Ulrich Drepper  <drepper@redhat.com>
 
+       * sysdeps/x86_64/__longjmp.S: Remove CHECK_RSP handling.  Fix CFI.
+       Remove incorrect use of BP_SYM.
+       * sysdeps/x86_64/____longjmp_chk.S: Rewrite.  Complete implementation
+       here now since it is more complex than just a simple check.
+
        * sysdeps/ia64/backtrace.c (backtrace_helper): Stop backtrace when
        we make no more progress.
 
index 030a0dc..50d2fca 100644 (file)
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+
        .section .rodata.str1.1,"aMS",@progbits,1
        .type   longjmp_msg,@object
 longjmp_msg:
@@ -23,7 +27,7 @@ longjmp_msg:
        .size   longjmp_msg, .-longjmp_msg
 
 
-#define __longjmp ____longjmp_chk
+//#define __longjmp ____longjmp_chk
 
 #ifdef PIC
 # define CALL_FAIL     leaq    longjmp_msg(%rip), %rdi;                      \
@@ -39,4 +43,103 @@ longjmp_msg:
        CALL_FAIL;                                                            \
 .Lok:
 
-#include "__longjmp.S"
+/* Jump to the position specified by ENV, causing the
+   setjmp call there to return VAL, or 1 if VAL is 0.
+   void __longjmp (__jmp_buf env, int val).  */
+       .text
+ENTRY(____longjmp_chk)
+       /* Restore registers.  */
+       movq    (JB_RSP*8)(%rdi),%r8
+       movq    (JB_RBP*8)(%rdi),%r9
+       movq    (JB_PC*8)(%rdi),%rdx
+#ifdef PTR_DEMANGLE
+       PTR_DEMANGLE (%r8)
+       PTR_DEMANGLE (%r9)
+       PTR_DEMANGLE (%rdx)
+#endif
+
+       /* Save function parameters.  */
+       movq    %rdi, %r10
+       movl    %esi, %ecx
+
+       xorl    %eax, %eax
+       cmpq    %r8, %rsp
+       jbe     .Lok
+
+       subq    $32, %rsp
+       cfi_adjust_cfa_offset(32)
+       movq    %r10, 24(%rsp)
+       xorl    %edi, %edi
+       movq    %rsp, %rsi
+       movl    $__NR_sigaltstack, %eax
+       syscall
+       movq    24(%rsp), %r10
+       testl   %eax, %eax
+       movl    $0, %eax
+       jne     .Lok
+       movl    8(%rsp), %eax
+       andl    $1, %eax
+
+.Lok:
+       /* We add unwind information for the target here.  */
+       cfi_def_cfa(%r10, 0)
+       cfi_register(%rsp,%r8)
+       cfi_register(%rbp,%r9)
+       cfi_register(%rip,%rdx)
+       cfi_offset(%rbx,JB_RBX*8)
+       cfi_offset(%r12,JB_R12*8)
+       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
+
+       /* Set return value for setjmp.  */
+.Lout: movl    %ecx, %eax
+       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, 8(%rsp)
+       je      .Lout
+
+.Lfail:        xchgq   %r8, %rsp
+       /* We want the stack trace to show that of the caller.  */
+       cfi_def_cfa(%rsp, 40)
+       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))
index 24552ec..b045c04 100644 (file)
@@ -34,16 +34,12 @@ ENTRY(__longjmp)
        PTR_DEMANGLE (%r9)
        PTR_DEMANGLE (%rdx)
 #endif
-#ifdef CHECK_RSP
-       CHECK_RSP (%r8)
-#endif
        /* 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)
        cfi_offset(%rbx,JB_RBX*8)
-       cfi_offset(%rbp,JB_RBP*8)
        cfi_offset(%r12,JB_R12*8)
        cfi_offset(%r13,JB_R13*8)
        cfi_offset(%r14,JB_R14*8)
@@ -58,4 +54,4 @@ ENTRY(__longjmp)
        movq %r8,%rsp
        movq %r9,%rbp
        jmpq *%rdx
-END (BP_SYM (__longjmp))
+END (__longjmp)