makecontext.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* Create new context.
  2. Copyright (C) 2001,2002,2005,2007,2008,2009 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
  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. ENTRY(__makecontext)
  19. movl 4(%esp), %eax
  20. /* Load the address of the function we are supposed to run. */
  21. movl 8(%esp), %ecx
  22. /* Compute the address of the stack. The information comes from
  23. to us_stack element. */
  24. movl oSS_SP(%eax), %edx
  25. movl %ecx, oEIP(%eax)
  26. addl oSS_SIZE(%eax), %edx
  27. /* Remember the number of parameters for the exit handler since
  28. it has to remove them. We store the number in the EBX register
  29. which the function we will call must preserve. */
  30. movl 12(%esp), %ecx
  31. movl %ecx, oEBX(%eax)
  32. /* Make room on the new stack for the parameters.
  33. Room for the arguments, return address (== L(exitcode)) and
  34. oLINK pointer is needed. One of the pointer sizes is subtracted
  35. after aligning the stack. */
  36. negl %ecx
  37. leal -4(%edx,%ecx,4), %edx
  38. negl %ecx
  39. /* Align the stack. */
  40. andl $0xfffffff0, %edx
  41. subl $4, %edx
  42. /* Store the future stack pointer. */
  43. movl %edx, oESP(%eax)
  44. /* Put the next context on the new stack (from the uc_link
  45. element). */
  46. movl oLINK(%eax), %eax
  47. movl %eax, 4(%edx,%ecx,4)
  48. /* Copy all the parameters. */
  49. jecxz 2f
  50. 1: movl 12(%esp,%ecx,4), %eax
  51. movl %eax, (%edx,%ecx,4)
  52. decl %ecx
  53. jnz 1b
  54. 2:
  55. /* If the function we call returns we must continue with the
  56. context which is given in the uc_link element. To do this
  57. set the return address for the function the user provides
  58. to a little bit of helper code which does the magic (see
  59. below). */
  60. #ifdef __PIC__
  61. call 1f
  62. cfi_adjust_cfa_offset (4)
  63. 1: popl %ecx
  64. cfi_adjust_cfa_offset (-4)
  65. addl $L(exitcode)-1b, %ecx
  66. movl %ecx, (%edx)
  67. #else
  68. movl $L(exitcode), (%edx)
  69. #endif
  70. /* 'makecontext' returns no value. */
  71. L(pseudo_end):
  72. ret
  73. /* This is the helper code which gets called if a function which
  74. is registered with 'makecontext' returns. In this case we
  75. have to install the context listed in the uc_link element of
  76. the context 'makecontext' manipulated at the time of the
  77. 'makecontext' call. If the pointer is NULL the process must
  78. terminate. */
  79. cfi_endproc
  80. L(exitcode):
  81. /* This removes the parameters passed to the function given to
  82. 'makecontext' from the stack. EBX contains the number of
  83. parameters (see above). */
  84. leal (%esp,%ebx,4), %esp
  85. #ifdef __PIC__
  86. call 1f
  87. 1: popl %ebx
  88. addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
  89. #endif
  90. cmpl $0, (%esp) /* Check the next context. */
  91. je 2f /* If it is zero exit. */
  92. call JUMPTARGET(__setcontext)
  93. /* If this returns (which can happen if the syscall fails) we'll
  94. exit the program with the return error value (-1). */
  95. movl %eax, (%esp)
  96. 2: call HIDDEN_JUMPTARGET(exit)
  97. /* The 'exit' call should never return. In case it does cause
  98. the process to terminate. */
  99. hlt
  100. cfi_startproc
  101. END(__makecontext)
  102. weak_alias (__makecontext, makecontext)