Optimize x86 and x86-64 ____longjmp_chk for Linux.
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / ____longjmp_chk.S
blob87c728d03b2ac77818fd9d8e8bb681d137265362
1 /* Copyright (C) 2001,2004,2005,2006,2009 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
19 #include <sysdep.h>
20 #include <jmpbuf-offsets.h>
21 #include <asm-syntax.h>
23         .section .rodata.str1.1,"aMS",@progbits,1
24         .type   longjmp_msg,@object
25 longjmp_msg:
26         .string "longjmp causes uninitialized stack frame"
27         .size   longjmp_msg, .-longjmp_msg
30 //#define __longjmp ____longjmp_chk
32 #ifdef PIC
33 # define CALL_FAIL      leaq    longjmp_msg(%rip), %rdi;                      \
34                         call    __GI___fortify_fail
35 #else
36 # define CALL_FAIL      movq    $longjmp_msg, %rdi;                           \
37                         call    __fortify_fail
38 #endif
40 #define CHECK_RSP(reg) \
41         cmpq    reg, %rsp;                                                    \
42         jbe     .Lok;                                                         \
43         CALL_FAIL;                                                            \
44 .Lok:
46 /* Jump to the position specified by ENV, causing the
47    setjmp call there to return VAL, or 1 if VAL is 0.
48    void __longjmp (__jmp_buf env, int val).  */
49         .text
50 ENTRY(____longjmp_chk)
51         /* Restore registers.  */
52         movq    (JB_RSP*8)(%rdi),%r8
53         movq    (JB_RBP*8)(%rdi),%r9
54         movq    (JB_PC*8)(%rdi),%rdx
55 #ifdef PTR_DEMANGLE
56         PTR_DEMANGLE (%r8)
57         PTR_DEMANGLE (%r9)
58         PTR_DEMANGLE (%rdx)
59 #endif
61         cmpq    %r8, %rsp
62         jbe     .Lok
64         /* Save function parameters.  */
65         movq    %rdi, %r10
66         movl    %esi, %ecx
68         xorl    %edi, %edi
69         leaq    -24(%rsp), %rsi
70         movl    $__NR_sigaltstack, %eax
71         syscall
72         /* Without working sigaltstack we cannot perform the test.  */
73         testl   %eax, %eax
74         jne     .Lok2
75         testl   $1, -16(%rsp)
76         jz      .Lfail
78         movq    -24(%rsp), %rax
79         addq    -8(%rsp), %rax
80         subq    %r8, %rax
81         cmpq    -8(%rsp), %rax
82         jae     .Lok2
84 .Lfail: CALL_FAIL
86 .Lok2:  movq    %r10, %rdi
87         movl    %ecx, %esi
89 .Lok:   /* We add unwind information for the target here.  */
90         cfi_def_cfa(%rdi, 0)
91         cfi_register(%rsp,%r8)
92         cfi_register(%rbp,%r9)
93         cfi_register(%rip,%rdx)
94         cfi_offset(%rbx,JB_RBX*8)
95         cfi_offset(%r12,JB_R12*8)
96         cfi_offset(%r13,JB_R13*8)
97         cfi_offset(%r14,JB_R14*8)
98         cfi_offset(%r15,JB_R15*8)
99         movq    (JB_RBX*8)(%rdi),%rbx
100         movq    (JB_R12*8)(%rdi),%r12
101         movq    (JB_R13*8)(%rdi),%r13
102         movq    (JB_R14*8)(%rdi),%r14
103         movq    (JB_R15*8)(%rdi),%r15
104         /* Set return value for setjmp.  */
105         movl    %esi, %eax
106         movq    %r8,%rsp
107         movq    %r9,%rbp
108         jmpq    *%rdx
109 END (BP_SYM (____longjmp_chk))