]>
Commit | Line | Data |
---|---|---|
dff8da6b | 1 | /* Copyright (C) 2009-2024 Free Software Foundation, Inc. |
a0902db9 DM |
2 | This file is part of the GNU C Library. |
3 | ||
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. | |
8 | ||
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. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 | 15 | License along with the GNU C Library; if not, see |
5a82c748 | 16 | <https://www.gnu.org/licenses/>. */ |
a0902db9 DM |
17 | |
18 | #include <sysdep.h> | |
88f4b692 | 19 | #include <pointer_guard.h> |
a0902db9 DM |
20 | #include <jmpbuf-offsets.h> |
21 | ||
22 | #define ENV(base,reg) [%base + (reg * 4)] | |
23 | #define ST_FLUSH_WINDOWS 3 | |
a0902db9 DM |
24 | |
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 | |
30 | ||
31 | .text | |
32 | ENTRY (____longjmp_chk) | |
33 | ld ENV(o0,JB_SP), %g5 | |
34 | #ifdef PTR_DEMANGLE | |
35 | PTR_DEMANGLE (%g5, %g5, %g4) | |
36 | #endif | |
37 | ||
38 | cmp %sp, %g5 | |
39 | bleu .Lok_norestore | |
40 | nop | |
41 | ||
42 | save %sp, -80, %sp | |
25ad0df1 DM |
43 | cfi_remember_state |
44 | cfi_def_cfa_register(%fp) | |
45 | cfi_window_save | |
46 | cfi_register(%o7, %i7) | |
a0902db9 DM |
47 | |
48 | clr %o0 | |
49 | add %sp, 64, %o1 | |
25ad0df1 | 50 | LOADSYSCALL(sigaltstack) |
a0902db9 DM |
51 | ta 0x10 |
52 | bcs .Lok | |
53 | ld [%sp + 64 + 4], %o2 | |
54 | andcc %o2, 0x1, %g0 | |
55 | be .Lfail | |
56 | ld [%sp + 64 + 0], %o0 | |
57 | ||
58 | ld [%sp + 64 + 8], %o1 | |
59 | add %o0, %o1, %o0 | |
25ad0df1 DM |
60 | sub %o0, %g5, %o0 |
61 | cmp %o0, %o1 | |
a0902db9 DM |
62 | bgeu .Lok |
63 | nop | |
64 | ||
65 | .Lfail: | |
3d2b3019 DM |
66 | #ifndef PIC |
67 | sethi %hi(longjmp_msg), %o0 | |
68 | or %o0, %lo(longjmp_msg), %o0 | |
69 | #else | |
70 | SETUP_PIC_REG(l7) | |
3d2b3019 DM |
71 | sethi %gdop_hix22(longjmp_msg), %o0 |
72 | xor %o0, %gdop_lox10(longjmp_msg), %o0 | |
73 | ld [%l7 + %o0], %o0, %gdop(longjmp_msg) | |
a0902db9 DM |
74 | #endif |
75 | call HIDDEN_JUMPTARGET(__fortify_fail) | |
76 | nop | |
77 | ||
78 | .Lok: | |
79 | restore | |
25ad0df1 | 80 | cfi_restore_state |
a0902db9 DM |
81 | |
82 | .Lok_norestore: | |
83 | ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */ | |
84 | #ifdef PTR_DEMANGLE | |
85 | PTR_DEMANGLE2 (%g3, %g3, %g4) | |
86 | #endif | |
87 | ||
88 | mov %o0, %g1 /* ENV in %g1 */ | |
89 | orcc %o1, %g0, %g2 /* VAL in %g2 */ | |
90 | be,a 0f /* Branch if zero; else skip delay slot. */ | |
91 | mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */ | |
92 | 0: | |
93 | ||
c0e70b25 | 94 | save %sp, -96, %sp |
a0902db9 DM |
95 | /* |
96 | * Do a "flush register windows trap". The trap handler in the | |
97 | * kernel writes all the register windows to their stack slots, and | |
98 | * marks them all as invalid (needing to be sucked up from the | |
99 | * stack when used). This ensures that all information needed to | |
100 | * unwind to these callers is in memory, not in the register | |
101 | * windows. | |
102 | */ | |
103 | ta ST_FLUSH_WINDOWS | |
104 | #ifdef PTR_DEMANGLE | |
105 | ld ENV(g1,JB_PC), %g1 /* Set return PC. */ | |
c0e70b25 | 106 | PTR_DEMANGLE2 (%i7, %g1, %g4) |
a0902db9 | 107 | #else |
c0e70b25 | 108 | ld ENV(g1,JB_PC), %i7 /* Set return PC. */ |
a0902db9 DM |
109 | #endif |
110 | mov %g5, %fp | |
c0e70b25 | 111 | jmp %i7 + 8 |
a0902db9 DM |
112 | restore %g2, 0, %o0 /* Restore values from above register frame. */ |
113 | ||
114 | END(____longjmp_chk) |