]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/x86_64/__longjmp.S
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / x86_64 / __longjmp.S
CommitLineData
dff8da6b 1/* Copyright (C) 2001-2024 Free Software Foundation, Inc.
c9cf6dde
AJ
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/>. */
c9cf6dde
AJ
17
18#include <sysdep.h>
88f4b692 19#include <pointer_guard.h>
a7140723 20#include <jmpbuf-offsets.h>
faaee1f0 21#include <jmp_buf-ssp.h>
c9cf6dde 22#include <asm-syntax.h>
8422c9a5 23#include <stap-probe.h>
c9cf6dde 24
faaee1f0
L
25/* Don't restore shadow stack register if
26 1. Shadow stack isn't enabled. Or
27 2. __longjmp is defined for __longjmp_cancel.
28 */
29#if !SHSTK_ENABLED || defined __longjmp
30# undef SHADOW_STACK_POINTER_OFFSET
31#endif
32
c9cf6dde
AJ
33/* Jump to the position specified by ENV, causing the
34 setjmp call there to return VAL, or 1 if VAL is 0.
35 void __longjmp (__jmp_buf env, int val). */
e7535de7 36 .text
c9cf6dde
AJ
37ENTRY(__longjmp)
38 /* Restore registers. */
eda41706 39 mov (JB_RSP*8)(%rdi),%R8_LP
6c7fb145 40 mov (JB_RBP*8)(%rdi),%R9_LP
eda41706 41 mov (JB_PC*8)(%rdi),%RDX_LP
ff8fecbe 42#ifdef PTR_DEMANGLE
eda41706 43 PTR_DEMANGLE (%R8_LP)
6c7fb145 44 PTR_DEMANGLE (%R9_LP)
eda41706 45 PTR_DEMANGLE (%RDX_LP)
6c7fb145
RM
46# ifdef __ILP32__
47 /* We ignored the high bits of the %rbp value because only the low
48 bits are mangled. But we cannot presume that %rbp is being used
49 as a pointer and truncate it, so recover the high bits. */
50 movl (JB_RBP*8 + 4)(%rdi), %eax
51 shlq $32, %rax
52 orq %rax, %r9
53# endif
faaee1f0
L
54#endif
55#ifdef SHADOW_STACK_POINTER_OFFSET
56# if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
57 /* Check if Shadow Stack is enabled. */
58 testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
59 jz L(skip_ssp)
60# else
61 xorl %eax, %eax
62# endif
63 /* Check and adjust the Shadow-Stack-Pointer. */
64 /* Get the current ssp. */
65 rdsspq %rax
66 /* And compare it with the saved ssp value. */
67 subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax
68 je L(skip_ssp)
69 /* Count the number of frames to adjust and adjust it
70 with incssp instruction. The instruction can adjust
71 the ssp by [0..255] value only thus use a loop if
72 the number of frames is bigger than 255. */
73 negq %rax
74 shrq $3, %rax
75 /* NB: We saved Shadow-Stack-Pointer of setjmp. Since we are
76 restoring Shadow-Stack-Pointer of setjmp's caller, we
77 need to unwind shadow stack by one more frame. */
78 addq $1, %rax
79
80 movl $255, %ebx
81L(loop):
82 cmpq %rbx, %rax
83 cmovb %rax, %rbx
84 incsspq %rbx
85 subq %rbx, %rax
86 ja L(loop)
87
88L(skip_ssp):
ff8fecbe 89#endif
8422c9a5 90 LIBC_PROBE (longjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RDX_LP)
7e7458e3
AJ
91 /* We add unwind information for the target here. */
92 cfi_def_cfa(%rdi, 0)
ff8fecbe
UD
93 cfi_register(%rsp,%r8)
94 cfi_register(%rbp,%r9)
95 cfi_register(%rip,%rdx)
7e7458e3 96 cfi_offset(%rbx,JB_RBX*8)
7e7458e3
AJ
97 cfi_offset(%r12,JB_R12*8)
98 cfi_offset(%r13,JB_R13*8)
99 cfi_offset(%r14,JB_R14*8)
100 cfi_offset(%r15,JB_R15*8)
c9cf6dde 101 movq (JB_RBX*8)(%rdi),%rbx
c9cf6dde
AJ
102 movq (JB_R12*8)(%rdi),%r12
103 movq (JB_R13*8)(%rdi),%r13
104 movq (JB_R14*8)(%rdi),%r14
105 movq (JB_R15*8)(%rdi),%r15
106 /* Set return value for setjmp. */
c9cf6dde 107 mov %esi, %eax
eda41706 108 mov %R8_LP,%RSP_LP
ff8fecbe 109 movq %r9,%rbp
8422c9a5
RM
110 LIBC_PROBE (longjmp_target, 3,
111 LP_SIZE@%RDI_LP, -4@%eax, LP_SIZE@%RDX_LP)
c9cf6dde 112 jmpq *%rdx
5ead9ce5 113END (__longjmp)