1 | /* longjmp for i386. |
2 | Copyright (C) 1995-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <sysdep.h> |
20 | #include <pointer_guard.h> |
21 | #include <jmpbuf-offsets.h> |
22 | #include <asm-syntax.h> |
23 | #include <stap-probe.h> |
24 | |
25 | .text |
26 | ENTRY (__longjmp) |
27 | #ifdef PTR_DEMANGLE |
28 | movl 4(%esp), %eax /* User's jmp_buf in %eax. */ |
29 | |
30 | /* Save the return address now. */ |
31 | movl (JB_PC*4)(%eax), %edx |
32 | /* Get the stack pointer. */ |
33 | movl (JB_SP*4)(%eax), %ecx |
34 | PTR_DEMANGLE (%edx) |
35 | PTR_DEMANGLE (%ecx) |
36 | LIBC_PROBE (longjmp, 3, 4@%eax, -4@8(%esp), 4@%edx) |
37 | cfi_def_cfa(%eax, 0) |
38 | cfi_register(%eip, %edx) |
39 | cfi_register(%esp, %ecx) |
40 | cfi_offset(%ebx, JB_BX*4) |
41 | cfi_offset(%esi, JB_SI*4) |
42 | cfi_offset(%edi, JB_DI*4) |
43 | cfi_offset(%ebp, JB_BP*4) |
44 | /* Restore registers. */ |
45 | movl (JB_BX*4)(%eax), %ebx |
46 | movl (JB_SI*4)(%eax), %esi |
47 | movl (JB_DI*4)(%eax), %edi |
48 | movl (JB_BP*4)(%eax), %ebp |
49 | cfi_restore(%ebx) |
50 | cfi_restore(%esi) |
51 | cfi_restore(%edi) |
52 | cfi_restore(%ebp) |
53 | |
54 | LIBC_PROBE (longjmp_target, 3, 4@%eax, -4@8(%esp), 4@%edx) |
55 | movl 8(%esp), %eax /* Second argument is return value. */ |
56 | movl %ecx, %esp |
57 | #else |
58 | movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ |
59 | movl 8(%esp), %eax /* Second argument is return value. */ |
60 | /* Save the return address now. */ |
61 | movl (JB_PC*4)(%ecx), %edx |
62 | LIBC_PROBE (longjmp, 3, 4@%ecx, -4@%eax, 4@%edx) |
63 | /* Restore registers. */ |
64 | movl (JB_BX*4)(%ecx), %ebx |
65 | movl (JB_SI*4)(%ecx), %esi |
66 | movl (JB_DI*4)(%ecx), %edi |
67 | movl (JB_BP*4)(%ecx), %ebp |
68 | movl (JB_SP*4)(%ecx), %esp |
69 | LIBC_PROBE (longjmp_target, 3, 4@%ecx, -4@%ecx, 4@%edx) |
70 | #endif |
71 | /* Jump to saved PC. */ |
72 | jmp *%edx |
73 | END (__longjmp) |
74 | |