Bug fixes for ____longjmp_chk on sparc.
[glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc64 / ____longjmp_chk.S
blob836e62efe7357876378a9f023dd78105e3a55455
1 /* Copyright (C) 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 /* longjmp is implemented in terms of the setcontext trap on Linux/Sparc64.  */
21 #include <sysdep.h>
23 /* Offsets into the jmp_buf structure.  */
25 #define O_mask_was_saved        512
26 #define O_gregs                 32
27 #define O_g1                    (O_gregs + 4*8)
28 #define O_sp                    (O_gregs + 17*8)
30 .section .rodata.str1.1,"aMS",@progbits,1
31         .type   longjmp_msg,@object
32 longjmp_msg:
33         .string "longjmp causes uninitialized stack frame"
34         .size   longjmp_msg, .-longjmp_msg
36         .text
37 ENTRY (____longjmp_chk)
38         ldx     [%o0 + O_sp], %o2
39         cmp     %sp, %o2
40         bleu,pt %xcc, .Lok
41          nop
43         save    %sp, -208, %sp
44         cfi_remember_state
45         cfi_def_cfa_register(%fp)
46         cfi_window_save
47         cfi_register(%o7, %i7)
48         add     %fp, 2023, %o1
49         clr     %o0
50         LOADSYSCALL(sigaltstack)
51         ta      0x6d
52         bcs,pn  %xcc, .Lok2
53          lduw   [%fp + 2031], %l2
54         andcc   %l2, 0x1, %g0
55         be,pn   %xcc, .Lfail
56          ldx    [%fp + 2023], %l0
57         ldx     [%fp + 2039], %l1
58         sub     %l0, STACK_BIAS, %l0
59         add     %l0, %l1, %l0
60         sub     %l0, %i2, %l0
61         cmp     %l0, %l1
62         bgeu,pt %xcc, .Lok2
63          nop
65 .Lfail:
66 #ifdef PIC
67 1:      call    2f
68         sethi   %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
69 2:      or      %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7
70         add     %l7, %o7, %l7
71 #endif
72         sethi   %hi(longjmp_msg), %o0
73         or      %o0, %lo(longjmp_msg), %o0
74 #ifdef PIC
75         ldx     [%l7 + %o0], %o0
76 #endif
77         call    HIDDEN_JUMPTARGET(__fortify_fail)
78          nop
80 .Lok2:  restore
81         cfi_restore_state
83 .Lok:
84         /* Modify the context with the value we want to return.  */
85         movre   %o1, 1, %o1
86         stx     %o1, [%o0 + O_g1]
88         /* Let setcontext know if we want to modify the current sigmask. */
89         ld      [%o0 + O_mask_was_saved], %o1
91         /* And bamf back to where we belong!  */
92         ta      0x6f
93 END(____longjmp_chk)