setjmpa.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. setjmpa.S
  9. Abstract:
  10. This module implements functionality for non-local goto statements.
  11. Author:
  12. Evan Green 28-Jul-2013
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/kernel/x86.inc>
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // Define the register offsets within the jump buffer. The first offset is a
  25. // boolean indicating whether or not the mask was saved. The next few are the
  26. // signal mask. If the size of the signal mask changes, these offsets will need
  27. // to be adjusted to make additional room.
  28. //
  29. .equ JUMP_BUFFER_SAVE_MASK, 0x00
  30. .equ JUMP_BUFFER_EBX, 0x0C
  31. .equ JUMP_BUFFER_ESI, 0x10
  32. .equ JUMP_BUFFER_EDI, 0x14
  33. .equ JUMP_BUFFER_EBP, 0x18
  34. .equ JUMP_BUFFER_ESP, 0x1C
  35. .equ JUMP_BUFFER_EIP, 0x20
  36. //
  37. // ----------------------------------------------------------------------- Code
  38. //
  39. //
  40. // .text specifies that this code belongs in the executable section.
  41. //
  42. // .code32 specifies that this is 32-bit protected mode code.
  43. //
  44. .text
  45. .code32
  46. //
  47. // int
  48. // setjmp (
  49. // jmp_buf Environment
  50. // )
  51. //
  52. /*++
  53. Routine Description:
  54. This routine saves the calling environment into the given buffer for
  55. later use by longjmp.
  56. Arguments:
  57. Environment - Supplies the pointer to the environment to save the
  58. application context in.
  59. Return Value:
  60. 0 if this was the direct call to set jump.
  61. Non-zero if this was a call from long jump.
  62. --*/
  63. EXPORTED_FUNCTION(_setjmp)
  64. END_FUNCTION(_setjmp)
  65. EXPORTED_FUNCTION(setjmp)
  66. movl (%esp), %ecx # Load the return address.
  67. leal 4(%esp), %edx # Get the caller's stack pointer.
  68. movl (%edx), %eax # Get the jump buffer.
  69. //
  70. // Mark the mask as having not been saved.
  71. //
  72. movl $0, JUMP_BUFFER_SAVE_MASK(%eax)
  73. //
  74. // Save the non-volatile registers.
  75. //
  76. movl %ebx, JUMP_BUFFER_EBX(%eax)
  77. movl %esi, JUMP_BUFFER_ESI(%eax)
  78. movl %edi, JUMP_BUFFER_EDI(%eax)
  79. movl %ebp, JUMP_BUFFER_EBP(%eax)
  80. movl %edx, JUMP_BUFFER_ESP(%eax)
  81. movl %ecx, JUMP_BUFFER_EIP(%eax)
  82. //
  83. // Return 0 as a direct call from set jump.
  84. //
  85. movl $0, %eax
  86. ret
  87. END_FUNCTION(setjmp)
  88. //
  89. // int
  90. // sigsetjmp (
  91. // sigjmp_buf Environment,
  92. // int SaveMask
  93. // )
  94. //
  95. /*++
  96. Routine Description:
  97. This routine saves the calling environment into the given buffer for
  98. later use by longjmp.
  99. Arguments:
  100. Environment - Supplies the pointer to the environment to save the
  101. application context in.
  102. SaveMask - Supplies a value indicating if the caller would like the
  103. current signal mask to be saved in the environment as well.
  104. Return Value:
  105. 0 if this was the direct call to setjmp.
  106. Non-zero if this was a call from longjmp.
  107. --*/
  108. EXPORTED_FUNCTION(sigsetjmp)
  109. movl (%esp), %ecx # Load the return address.
  110. leal 4(%esp), %edx # Get the caller's stack pointer.
  111. movl (%edx), %eax # Get the jump buffer.
  112. //
  113. // Mark the mask as having not been saved.
  114. //
  115. movl $0, JUMP_BUFFER_SAVE_MASK(%eax)
  116. //
  117. // Save the non-volatile registers.
  118. //
  119. movl %ebx, JUMP_BUFFER_EBX(%eax)
  120. movl %esi, JUMP_BUFFER_ESI(%eax)
  121. movl %edi, JUMP_BUFFER_EDI(%eax)
  122. movl %ebp, JUMP_BUFFER_EBP(%eax)
  123. movl %edx, JUMP_BUFFER_ESP(%eax)
  124. movl %ecx, JUMP_BUFFER_EIP(%eax)
  125. //
  126. // Call the internal set jump C routine to help save the signal mask if
  127. // needed.
  128. //
  129. movl 8(%esp), %ecx # Get the SaveMask parameter.
  130. pushl %ecx # Push the SaveMask parameter.
  131. pushl %eax # Push the jump buffer parameter.
  132. call ClpSetJump # Call the helper.
  133. addl $8, %esp # Pop the parameters.
  134. //
  135. // Return 0 as a direct call from set jump.
  136. //
  137. movl $0, %eax
  138. ret
  139. END_FUNCTION(sigsetjmp)
  140. //
  141. // void
  142. // ClpLongJump (
  143. // jmp_buf Environment,
  144. // int Value
  145. // )
  146. //
  147. /*++
  148. Routine Description:
  149. This routine restores given environment.
  150. Arguments:
  151. Environment - Supplies a pointer to the environment to restore.
  152. Value - Supplies the value to make appear as the return value from the
  153. set jump function.
  154. Return Value:
  155. None, the function does not return.
  156. --*/
  157. .equ Environment, 4
  158. .equ Value, 8
  159. FUNCTION(ClpLongJump)
  160. movl Environment(%esp), %ecx # Get the environment buffer.
  161. movl Value(%esp), %eax # Get the return value in position.
  162. //
  163. // Restore the non-volatile registers.
  164. //
  165. movl JUMP_BUFFER_EBX(%ecx), %ebx
  166. movl JUMP_BUFFER_ESI(%ecx), %esi
  167. movl JUMP_BUFFER_EDI(%ecx), %edi
  168. movl JUMP_BUFFER_EBP(%ecx), %ebp
  169. movl JUMP_BUFFER_ESP(%ecx), %esp
  170. //
  171. // Get and jump to the original EIP.
  172. //
  173. movl JUMP_BUFFER_EIP(%ecx), %edx
  174. jmp *%edx
  175. END_FUNCTION(ClpLongJump)