Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / ____longjmp_chk.S
blob49f0384ba8a802f36e3cfa298277860273b48744
1 /* Copyright (C) 2001-2014 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, see
16    <http://www.gnu.org/licenses/>.  */
18 #include <sysdep.h>
19 #include <jmpbuf-offsets.h>
20 #include <asm-syntax.h>
21 #include <stap-probe.h>
23 #include <sigaltstack-offsets.h>
25         .section .rodata.str1.1,"aMS",@progbits,1
26         .type   longjmp_msg,@object
27 longjmp_msg:
28         .string "longjmp causes uninitialized stack frame"
29         .size   longjmp_msg, .-longjmp_msg
32 //#define __longjmp ____longjmp_chk
34 #ifdef PIC
35 # define CALL_FAIL      sub     $8, %RSP_LP;                                  \
36                         cfi_remember_state;                                   \
37                         cfi_def_cfa_offset(16);                               \
38                         lea     longjmp_msg(%rip), %RDI_LP;                   \
39                         call    HIDDEN_JUMPTARGET(__fortify_fail);            \
40                         nop;                                                  \
41                         cfi_restore_state
42 #else
43 # define CALL_FAIL      sub     $8, %RSP_LP;                                  \
44                         cfi_remember_state;                                   \
45                         cfi_def_cfa_offset(16);                               \
46                         mov     $longjmp_msg, %RDI_LP;                        \
47                         call    HIDDEN_JUMPTARGET(__fortify_fail);            \
48                         nop;                                                  \
49                         cfi_restore_state
50 #endif
52 /* Jump to the position specified by ENV, causing the
53    setjmp call there to return VAL, or 1 if VAL is 0.
54    void __longjmp (__jmp_buf env, int val).  */
55         .text
56 ENTRY(____longjmp_chk)
57         /* Restore registers.  */
58         mov     (JB_RSP*8)(%rdi), %R8_LP
59         mov     (JB_RBP*8)(%rdi),%R9_LP
60         mov     (JB_PC*8)(%rdi), %RDX_LP
61 #ifdef PTR_DEMANGLE
62         PTR_DEMANGLE (%R8_LP)
63         PTR_DEMANGLE (%R9_LP)
64         PTR_DEMANGLE (%RDX_LP)
65 # ifdef __ILP32__
66         /* We ignored the high bits of the %rbp value because only the low
67            bits are mangled.  But we cannot presume that %rbp is being used
68            as a pointer and truncate it, so recover the high bits.  */
69         movl (JB_RBP*8 + 4)(%rdi), %eax
70         shlq $32, %rax
71         orq %rax, %r9
72 # endif
73 #endif
75         cmp     %R8_LP, %RSP_LP
76         jbe     .Lok
78         /* Save function parameters.  */
79         movq    %rdi, %r10
80         cfi_register (%rdi, %r10)
81         movl    %esi, %ebx
82         cfi_register (%rsi, %rbx)
84         xorl    %edi, %edi
85         lea     -sizeSS(%rsp), %RSI_LP
86         movl    $__NR_sigaltstack, %eax
87         syscall
88         /* Without working sigaltstack we cannot perform the test.  */
89         testl   %eax, %eax
90         jne     .Lok2
91         testl   $1, (-sizeSS + oSS_FLAGS)(%rsp)
92         jz      .Lfail
94         mov     (-sizeSS + oSS_SP)(%rsp), %RAX_LP
95         add     (-sizeSS + oSS_SIZE)(%rsp), %RAX_LP
96         sub     %R8_LP, %RAX_LP
97         cmp     (-sizeSS + oSS_SIZE)(%rsp), %RAX_LP
98         jae     .Lok2
100 .Lfail: CALL_FAIL
102 .Lok2:  movq    %r10, %rdi
103         cfi_restore (%rdi)
104         movl    %ebx, %esi
105         cfi_restore (%rsi)
107 .Lok:
108         LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
109         /* We add unwind information for the target here.  */
110         cfi_def_cfa(%rdi, 0)
111         cfi_register(%rsp,%r8)
112         cfi_register(%rbp,%r9)
113         cfi_register(%rip,%rdx)
114         cfi_offset(%rbx,JB_RBX*8)
115         cfi_offset(%r12,JB_R12*8)
116         cfi_offset(%r13,JB_R13*8)
117         cfi_offset(%r14,JB_R14*8)
118         cfi_offset(%r15,JB_R15*8)
119         movq    (JB_RBX*8)(%rdi), %rbx
120         movq    (JB_R12*8)(%rdi), %r12
121         movq    (JB_R13*8)(%rdi), %r13
122         movq    (JB_R14*8)(%rdi), %r14
123         movq    (JB_R15*8)(%rdi), %r15
124         /* Set return value for setjmp.  */
125         movl    %esi, %eax
126         mov     %R8_LP, %RSP_LP
127         movq    %r9,%rbp
128         LIBC_PROBE (longjmp_target, 3,
129                     LP_SIZE@%RDI_LP, -4@%eax, LP_SIZE@%RDX_LP)
130         jmpq    *%rdx
131 END (____longjmp_chk)