setjmp.S 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* setjmp for x86-64.
  2. Copyright (C) 2001-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  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. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <sysdep.h>
  16. #include <pointer_guard.h>
  17. #include <jmpbuf-offsets.h>
  18. #include <jmp_buf-ssp.h>
  19. #include <asm-syntax.h>
  20. #include <stap-probe.h>
  21. /* Don't save shadow stack register if shadow stack isn't enabled. */
  22. #if !SHSTK_ENABLED
  23. # undef SHADOW_STACK_POINTER_OFFSET
  24. #endif
  25. ENTRY (__sigsetjmp)
  26. /* Save registers. */
  27. movq %rbx, (JB_RBX*8)(%rdi)
  28. #ifdef PTR_MANGLE
  29. # ifdef __ILP32__
  30. /* Save the high bits of %rbp first, since PTR_MANGLE will
  31. only handle the low bits but we cannot presume %rbp is
  32. being used as a pointer and truncate it. Here we write all
  33. of %rbp, but the low bits will be overwritten below. */
  34. movq %rbp, (JB_RBP*8)(%rdi)
  35. # endif
  36. mov %RBP_LP, %RAX_LP
  37. PTR_MANGLE (%RAX_LP)
  38. mov %RAX_LP, (JB_RBP*8)(%rdi)
  39. #else
  40. movq %rbp, (JB_RBP*8)(%rdi)
  41. #endif
  42. movq %r12, (JB_R12*8)(%rdi)
  43. movq %r13, (JB_R13*8)(%rdi)
  44. movq %r14, (JB_R14*8)(%rdi)
  45. movq %r15, (JB_R15*8)(%rdi)
  46. lea 8(%rsp), %RDX_LP /* Save SP as it will be after we return. */
  47. #ifdef PTR_MANGLE
  48. PTR_MANGLE (%RDX_LP)
  49. #endif
  50. movq %rdx, (JB_RSP*8)(%rdi)
  51. mov (%rsp), %RAX_LP /* Save PC we are returning to now. */
  52. LIBC_PROBE (setjmp, 3, LP_SIZE@%RDI_LP, -4@%esi, LP_SIZE@%RAX_LP)
  53. #ifdef PTR_MANGLE
  54. PTR_MANGLE (%RAX_LP)
  55. #endif
  56. movq %rax, (JB_PC*8)(%rdi)
  57. #ifdef SHADOW_STACK_POINTER_OFFSET
  58. # if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
  59. /* Check if Shadow Stack is enabled. */
  60. testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
  61. jz L(skip_ssp)
  62. # else
  63. xorl %eax, %eax
  64. # endif
  65. /* Get the current Shadow-Stack-Pointer and save it. */
  66. rdsspq %rax
  67. movq %rax, SHADOW_STACK_POINTER_OFFSET(%rdi)
  68. # if IS_IN (libc) && defined SHARED && defined FEATURE_1_OFFSET
  69. L(skip_ssp):
  70. # endif
  71. #endif
  72. #if IS_IN (rtld)
  73. /* In ld.so we never save the signal mask. */
  74. xorl %eax, %eax
  75. retq
  76. #else
  77. /* Make a tail call to __sigjmp_save; it takes the same args. */
  78. jmp __sigjmp_save
  79. #endif
  80. END (__sigsetjmp)
  81. hidden_def (__sigsetjmp)