| 1 | /* setjmp for x86-64. | 
|---|
| 2 | Copyright (C) 2001-2020 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 <jmpbuf-offsets.h> | 
|---|
| 21 | #include <jmp_buf-ssp.h> | 
|---|
| 22 | #include <asm-syntax.h> | 
|---|
| 23 | #include <stap-probe.h> | 
|---|
| 24 |  | 
|---|
| 25 | /* Don't save shadow stack register if shadow stack isn't enabled.  */ | 
|---|
| 26 | #if !SHSTK_ENABLED | 
|---|
| 27 | # undef SHADOW_STACK_POINTER_OFFSET | 
|---|
| 28 | #endif | 
|---|
| 29 |  | 
|---|
| 30 | ENTRY (__sigsetjmp) | 
|---|
| 31 | /* Save registers.  */ | 
|---|
| 32 | movq %rbx, (JB_RBX*8)(%rdi) | 
|---|
| 33 | #ifdef PTR_MANGLE | 
|---|
| 34 | # ifdef __ILP32__ | 
|---|
| 35 | /* Save the high bits of %rbp first, since PTR_MANGLE will | 
|---|
| 36 | only handle the low bits but we cannot presume %rbp is | 
|---|
| 37 | being used as a pointer and truncate it.  Here we write all | 
|---|
| 38 | of %rbp, but the low bits will be overwritten below.  */ | 
|---|
| 39 | movq %rbp, (JB_RBP*8)(%rdi) | 
|---|
| 40 | # endif | 
|---|
| 41 | mov %RBP_LP, %RAX_LP | 
|---|
| 42 | PTR_MANGLE (%RAX_LP) | 
|---|
| 43 | mov %RAX_LP, (JB_RBP*8)(%rdi) | 
|---|
| 44 | #else | 
|---|
| 45 | movq %rbp, (JB_RBP*8)(%rdi) | 
|---|
| 46 | #endif | 
|---|
| 47 | movq %r12, (JB_R12*8)(%rdi) | 
|---|
| 48 | movq %r13, (JB_R13*8)(%rdi) | 
|---|
| 49 | movq %r14, (JB_R14*8)(%rdi) | 
|---|
| 50 | movq %r15, (JB_R15*8)(%rdi) | 
|---|
| 51 | lea 8(%rsp), %RDX_LP	/* Save SP as it will be after we return.  */ | 
|---|
| 52 | #ifdef PTR_MANGLE | 
|---|
| 53 | PTR_MANGLE (%RDX_LP) | 
|---|
| 54 | #endif | 
|---|
| 55 | movq %rdx, (JB_RSP*8)(%rdi) | 
|---|
| 56 | mov (%rsp), %RAX_LP	/* Save PC we are returning to now.  */ | 
|---|
| 57 | LIBC_PROBE (setjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RAX_LP) | 
|---|
| 58 | #ifdef PTR_MANGLE | 
|---|
| 59 | PTR_MANGLE (%RAX_LP) | 
|---|
| 60 | #endif | 
|---|
| 61 | movq %rax, (JB_PC*8)(%rdi) | 
|---|
| 62 |  | 
|---|
| 63 | #ifdef SHADOW_STACK_POINTER_OFFSET | 
|---|
| 64 | # if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET | 
|---|
| 65 | /* Check if Shadow Stack is enabled.  */ | 
|---|
| 66 | testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET | 
|---|
| 67 | jz L(skip_ssp) | 
|---|
| 68 | # else | 
|---|
| 69 | xorl %eax, %eax | 
|---|
| 70 | # endif | 
|---|
| 71 | /* Get the current Shadow-Stack-Pointer and save it.  */ | 
|---|
| 72 | rdsspq %rax | 
|---|
| 73 | movq %rax, SHADOW_STACK_POINTER_OFFSET(%rdi) | 
|---|
| 74 | # if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET | 
|---|
| 75 | L(skip_ssp): | 
|---|
| 76 | # endif | 
|---|
| 77 | #endif | 
|---|
| 78 | #if IS_IN (rtld) | 
|---|
| 79 | /* In ld.so we never save the signal mask.  */ | 
|---|
| 80 | xorl %eax, %eax | 
|---|
| 81 | retq | 
|---|
| 82 | #else | 
|---|
| 83 | /* Make a tail call to __sigjmp_save; it takes the same args.  */ | 
|---|
| 84 | jmp __sigjmp_save | 
|---|
| 85 | #endif | 
|---|
| 86 | END (__sigsetjmp) | 
|---|
| 87 | hidden_def (__sigsetjmp) | 
|---|
| 88 |  | 
|---|