]>
Commit | Line | Data |
---|---|---|
2b778ceb | 1 | /* Copyright (C) 2001-2021 Free Software Foundation, Inc. |
02937d82 ST |
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 | |
15 | License along with the GNU C Library; if not, see | |
16 | <https://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include <sysdep.h> | |
19 | #include <jmpbuf-offsets.h> | |
20 | #include <tcb-offsets.h> | |
21 | #include <asm-syntax.h> | |
22 | ||
23 | #include <signal-defines.h> | |
24 | /* #include <signal.h> */ | |
25 | #define SS_ONSTACK 1 | |
26 | ||
27 | .text | |
28 | ENTRY (__longjmp) | |
29 | movl 4(%esp), %eax /* User's jmp_buf in %eax. */ | |
30 | ||
31 | /* Save the return address now. */ | |
32 | movl (JB_PC*4)(%eax), %edx | |
33 | /* Get the stack pointer. */ | |
34 | movl (JB_SP*4)(%eax), %ecx | |
35 | cfi_undefined(%ecx) | |
36 | #ifdef PTR_DEMANGLE | |
37 | PTR_DEMANGLE (%edx) | |
38 | PTR_DEMANGLE (%ecx) | |
39 | #endif | |
40 | ||
115bcf92 ST |
41 | movw %ds, %si |
42 | movw %gs, %di | |
43 | cmpw %si, %di | |
44 | jz .Lok /* TLS not initialized yet */ | |
45 | ||
46 | movl %gs:SIGSTATE_OFFSET, %edi | |
47 | testl %edi, %edi | |
5baad9a6 | 48 | jz .Lok /* sigstate not initialized yet */ |
02937d82 ST |
49 | |
50 | testl $SS_ONSTACK, (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_FLAGS__OFFSET)(%edi) | |
51 | jz .Lok | |
52 | ||
53 | /* We were on the alternate stack. */ | |
54 | ||
55 | cmpl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SP__OFFSET)(%edi), %ecx | |
56 | jb .Loks /* We jump below the alternate stack, switch. */ | |
57 | ||
58 | movl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SP__OFFSET)(%edi), %ebx | |
59 | addl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%edi), %ebx | |
60 | cmpl %ebx, %ecx | |
61 | jb .Lok /* We jump inside the alternate stack, do not switch. */ | |
62 | ||
63 | /* We jump above the alternate stack, switch. */ | |
64 | ||
65 | .Loks: /* We jump out of the alternate stack, clear SS_ONSTACK flag. */ | |
66 | andl $~(SS_ONSTACK), (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_FLAGS__OFFSET)(%edi) | |
67 | ||
68 | .Lok: /* We add unwind information for the target here. */ | |
69 | cfi_def_cfa(%eax, 0) | |
70 | cfi_register(%eip, %edx) | |
71 | cfi_register(%esp, %ecx) | |
72 | cfi_offset(%ebx, JB_BX*4) | |
73 | cfi_offset(%esi, JB_SI*4) | |
74 | cfi_offset(%edi, JB_DI*4) | |
75 | cfi_offset(%ebp, JB_BP*4) | |
76 | /* Restore registers. */ | |
77 | movl (JB_BX*4)(%eax), %ebx | |
78 | movl (JB_SI*4)(%eax), %esi | |
79 | movl (JB_DI*4)(%eax), %edi | |
80 | movl (JB_BP*4)(%eax), %ebp | |
81 | cfi_restore(%ebx) | |
82 | cfi_restore(%esi) | |
83 | cfi_restore(%edi) | |
84 | cfi_restore(%ebp) | |
85 | ||
86 | movl 8(%esp), %eax /* Second argument is return value. */ | |
87 | movl %ecx, %esp | |
88 | ||
89 | /* Jump to saved PC. */ | |
90 | jmp *%edx | |
91 | END (__longjmp) |