Update copyright notices with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / i386 / ____longjmp_chk.S
blobda75289aaf848ca825c2f59121cea289de864234
1 /* Copyright (C) 2001-2013 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>
24         .section .rodata.str1.1,"aMS",@progbits,1
25         .type   longjmp_msg,@object
26 longjmp_msg:
27         .string "longjmp causes uninitialized stack frame"
28         .size   longjmp_msg, .-longjmp_msg
31 #ifdef PIC
32 # define CALL_FAIL      movl    %ebx, %ecx;                                   \
33                         cfi_register(%ebx,%ecx);                              \
34                         LOAD_PIC_REG (bx);                                    \
35                         leal    longjmp_msg@GOTOFF(%ebx), %eax;               \
36                         call    HIDDEN_JUMPTARGET(__fortify_fail)
37 #else
38 # define CALL_FAIL      movl    $longjmp_msg, %eax;                           \
39                         call    HIDDEN_JUMPTARGET(__fortify_fail)
40 #endif
43         .text
44 ENTRY (____longjmp_chk)
45         movl    4(%esp), %ecx   /* User's jmp_buf in %ecx.  */
47         /* Save the return address now.  */
48         movl    (JB_PC*4)(%ecx), %edx
49         /* Get the stack pointer.  */
50         movl    (JB_SP*4)(%ecx), %edi
51         cfi_undefined(%edi)
52         PTR_DEMANGLE (%edx)
53         PTR_DEMANGLE (%edi)
55         cmpl    %edi, %esp
56         jbe     .Lok
58         subl    $12, %esp
59         cfi_adjust_cfa_offset(12)
60         xorl    %ebx, %ebx
61         movl    %esp, %ecx
62         movl    $__NR_sigaltstack, %eax
63         ENTER_KERNEL
64         /* Without working sigaltstack we cannot perform the test.  */
65         test    %eax, %eax
66         jne     .Lok2
67         testl   $1, 4(%esp)
68         jz      .Lfail
70         movl    (%esp), %eax
71         addl    8(%esp), %eax
72         subl    %edi, %eax
73         cmpl    8(%esp), %eax
74         jae     .Lok2
76 .Lfail: CALL_FAIL
78 .Lok2:  addl    $12, %esp
79         cfi_adjust_cfa_offset(-12)
80         movl    4(%esp), %ecx
82 .Lok:
83         LIBC_PROBE (longjmp, 3, 4@%ecx, -4@8(%esp), 4@%edx)
84         /* We add unwind information for the target here.  */
85         cfi_def_cfa(%ecx, 0)
86         cfi_register(%eip, %edx)
87         cfi_register(%esp, %edi)
88         cfi_offset(%ebx, JB_BX*4)
89         cfi_offset(%esi, JB_SI*4)
90         cfi_offset(%edi, JB_DI*4)
91         cfi_offset(%ebp, JB_BP*4)
93         movl    8(%esp), %eax   /* Second argument is return value.  */
94         movl    %edi, %esp
96         /* Restore registers.  */
97         movl    (JB_BX*4)(%ecx), %ebx
98         movl    (JB_SI*4)(%ecx), %esi
99         movl    (JB_DI*4)(%ecx), %edi
100         movl    (JB_BP*4)(%ecx), %ebp
101         cfi_restore(%ebx)
102         cfi_restore(%esi)
103         cfi_restore(%edi)
104         cfi_restore(%ebp)
106         /* Jump to saved PC.  */
107         LIBC_PROBE (longjmp_target, 3, 4@%ecx, -4@%eax, 4@%edx)
108         jmp     *%edx
109 END (____longjmp_chk)