setcontext.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* Install given context.
  2. Copyright (C) 2002-2012 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Andreas Jaeger <aj@suse.de>, 2002.
  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. 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. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #include <sysdep.h>
  17. #include "ucontext_i.h"
  18. /* int __setcontext (const ucontext_t *ucp)
  19. Restores the machine context in UCP and thereby resumes execution
  20. in that context.
  21. This implementation is intended to be used for *synchronous* context
  22. switches only. Therefore, it does not have to restore anything
  23. other than the PRESERVED state. */
  24. ENTRY(__setcontext)
  25. /* Save argument since syscall will destroy it. */
  26. pushq %rdi
  27. cfi_adjust_cfa_offset(8)
  28. /* Set the signal mask with
  29. rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
  30. leaq oSIGMASK(%rdi), %rsi
  31. xorl %edx, %edx
  32. movl $SIG_SETMASK, %edi
  33. movl $_NSIG8,%r10d
  34. movl $__NR_rt_sigprocmask, %eax
  35. syscall
  36. popq %rdi /* Reload %rdi, adjust stack. */
  37. cfi_adjust_cfa_offset(-8)
  38. cmpq $-4095, %rax /* Check %rax for error. */
  39. jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
  40. /* Restore the floating-point context. Not the registers, only the
  41. rest. */
  42. movq oFPREGS(%rdi), %rcx
  43. fldenv (%rcx)
  44. ldmxcsr oMXCSR(%rdi)
  45. /* Load the new stack pointer, the preserved registers and
  46. registers used for passing args. */
  47. cfi_def_cfa(%rdi, 0)
  48. cfi_offset(%rbx,oRBX)
  49. cfi_offset(%rbp,oRBP)
  50. cfi_offset(%r12,oR12)
  51. cfi_offset(%r13,oR13)
  52. cfi_offset(%r14,oR14)
  53. cfi_offset(%r15,oR15)
  54. cfi_offset(%rsp,oRSP)
  55. cfi_offset(%rip,oRIP)
  56. movq oRSP(%rdi), %rsp
  57. movq oRBX(%rdi), %rbx
  58. movq oRBP(%rdi), %rbp
  59. movq oR12(%rdi), %r12
  60. movq oR13(%rdi), %r13
  61. movq oR14(%rdi), %r14
  62. movq oR15(%rdi), %r15
  63. /* The following ret should return to the address set with
  64. getcontext. Therefore push the address on the stack. */
  65. movq oRIP(%rdi), %rcx
  66. pushq %rcx
  67. movq oRSI(%rdi), %rsi
  68. movq oRDX(%rdi), %rdx
  69. movq oRCX(%rdi), %rcx
  70. movq oR8(%rdi), %r8
  71. movq oR9(%rdi), %r9
  72. /* Setup finally %rdi. */
  73. movq oRDI(%rdi), %rdi
  74. /* End FDE here, we fall into another context. */
  75. cfi_endproc
  76. cfi_startproc
  77. /* Clear rax to indicate success. */
  78. xorl %eax, %eax
  79. L(pseudo_end):
  80. ret
  81. PSEUDO_END(__setcontext)
  82. weak_alias (__setcontext, setcontext)