contexta.S 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*++
  2. Copyright (c) 2016 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. contexta.S
  9. Abstract:
  10. This module implements assembly functionality for working with ucontext
  11. structures.
  12. Author:
  13. Evan Green 9-Sep-2016
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/x64.inc>
  21. //
  22. // ---------------------------------------------------------------- Definitions
  23. //
  24. //
  25. // ----------------------------------------------------------------------- Code
  26. //
  27. ASSEMBLY_FILE_HEADER
  28. //
  29. // LIBC_API
  30. // int
  31. // getcontext (
  32. // ucontext_t *Context
  33. // )
  34. //
  35. /*++
  36. Routine Description:
  37. This routine saves the current user context into the given structure,
  38. including the machine registers, signal mask, and execution stack pointer.
  39. If restored, the returned context will appear to execute at the return from
  40. this function.
  41. Arguments:
  42. Context - Supplies a pointer where the current context is saved.
  43. Return Value:
  44. 0 on success.
  45. -1 on failure, and errno will be set to contain more information.
  46. --*/
  47. EXPORTED_FUNCTION(getcontext)
  48. int $3 # TODO: Check this, it's never been run!
  49. movq %rdi, %rax # Get the context.
  50. addq $SIGNAL_CONTEXT_SIZE, %rax # Get to the TRAP_FRAME part.
  51. movq %rcx, TRAP_RCX(%rax) # Save rcx.
  52. xorq %rcx, %rcx # Clear a register.
  53. movw %cs, %cx # Get DS.
  54. movq %rcx, TRAP_CS(%rax) # Save CS.
  55. movw %ds, %cx # Get DS.
  56. movq %rcx, TRAP_DS(%rax) # Save DS.
  57. movw %es, %cx # Get ES.
  58. movq %rcx, TRAP_ES(%rax) # Save ES.
  59. movw %fs, %cx # Get FS.
  60. movq %rcx, TRAP_FS(%rax) # Save FS.
  61. movw %gs, %cx # Get GS.
  62. movq %rcx, TRAP_GS(%rax) # Save GS.
  63. movw %ss, %cx # Get SS.
  64. movq %rcx, TRAP_SS(%rax) # Save SS.
  65. xorq %rcx, %rcx # Clear a register.
  66. movq %rcx, TRAP_RAX(%rax) # Save a zeroed rax.
  67. movq %rbx, TRAP_RBX(%rax) # Save rbx.
  68. movq %rdx, TRAP_RDX(%rax) # Save rdx.
  69. movq %rsi, TRAP_RSI(%rax) # Save rsi.
  70. movq %rdi, TRAP_RDI(%rax) # Save rdi.
  71. movq %rbp, TRAP_RBP(%rax) # Save rbp.
  72. movq %r8, TRAP_R8(%rax) # Save r8.
  73. movq %r9, TRAP_R9(%rax) # Save r9.
  74. movq %r10, TRAP_R10(%rax) # Save r10.
  75. movq %r11, TRAP_R11(%rax) # Save r11.
  76. movq %r12, TRAP_R12(%rax) # Save r12.
  77. movq %r13, TRAP_R13(%rax) # Save r13.
  78. movq %r14, TRAP_R14(%rax) # Save r14.
  79. movq %r15, TRAP_R15(%rax) # Save r15.
  80. movq %rcx, TRAP_ERRORCODE(%rax) # Save zeroed error code.
  81. movq (%rsp), %rcx # Get the return address.
  82. movq %rcx, TRAP_RIP(%rax) # Save the instruction pointer.
  83. pushfq # Push eflags.
  84. popq %rcx # Get eflags.
  85. movq %rcx, TRAP_RFLAGS(%rax) # Save eflags.
  86. leaq 4(%rsp), %rcx # Get the stack pointer (w/o return addr).
  87. movq %rcx, TRAP_RSP(%rax) # Save that as rsp.
  88. movq %rsp, %rsi # Set stack pointer as second arg.
  89. call ClpGetContext # Call the C helper.
  90. ret # Return whatever the C routine returned.
  91. END_FUNCTION(getcontext)
  92. //
  93. // LIBC_API
  94. // int
  95. // setcontext (
  96. // const ucontext_t *Context
  97. // )
  98. //
  99. /*++
  100. Routine Description:
  101. This routine restores a previous execution context into the current
  102. processor.
  103. Arguments:
  104. Context - Supplies a pointer to the previously saved context to restore.
  105. Return Value:
  106. Does not return on success, as execution continues from the new context.
  107. -1 on failure, and errno will be set to contain more information.
  108. --*/
  109. EXPORTED_FUNCTION(setcontext)
  110. int $3 # TODO: Check this, it's never been run!
  111. pushq %rdi # Save the argument.
  112. call ClpSetContext # Call the C helper.
  113. popq %rcx # Restore the argument.
  114. addq $SIGNAL_CONTEXT_SIZE, %rcx # Get to the TRAP_FRAME part.
  115. movq TRAP_DS(%rcx), %rax # Get DS.
  116. movw %ax, %ds # Restore DS.
  117. movq TRAP_ES(%rcx), %rax # Get ES.
  118. movw %ax, %es # Restore ES.
  119. movq TRAP_FS(%rcx), %rax # Get FS.
  120. movw %ax, %fs # Restore FS.
  121. movq TRAP_GS(%rcx), %rax # Get GS.
  122. movw %ax, %gs # Restore GS.
  123. movq TRAP_SS(%rcx), %rax # Get SS.
  124. movw %ax, %ss # Restore SS.
  125. movq TRAP_R15(%rcx), %r15 # Restore r15.
  126. movq TRAP_R14(%rcx), %r14 # Restore r14.
  127. movq TRAP_R13(%rcx), %r13 # Restore r13.
  128. movq TRAP_R12(%rcx), %r12 # Restore r12.
  129. movq TRAP_R11(%rcx), %r11 # Restore r11.
  130. movq TRAP_R10(%rcx), %r10 # Restore r10.
  131. movq TRAP_R9(%rcx), %r9 # Restore r9.
  132. movq TRAP_R8(%rcx), %r8 # Restore r8.
  133. movq TRAP_RBP(%rcx), %rbp # Restore rbp.
  134. movq TRAP_RDI(%rcx), %rdi # Restore rdi.
  135. movq TRAP_RSI(%rcx), %rsi # Restore rsi.
  136. movq TRAP_RDX(%rcx), %rdx # Restore rdx.
  137. movq TRAP_RBX(%rcx), %rbx # Restore rbx.
  138. movq TRAP_RFLAGS(%rcx), %rax # Get eflags.
  139. pushq %rax # Push eflags.
  140. popfq # Pop eflags off the stack.
  141. movq TRAP_RAX(%rcx), %rax # Restore rax as return value.
  142. //
  143. // This last part gets a little fishy depending on where the context
  144. // structure is. If the new rsp is on the same stack but greater than this
  145. // one, then this code runs the risk of taking a signal, which might
  146. // clobber the context before restoring RIP can be done. Hopefully that
  147. // doesn't happen.
  148. //
  149. movq TRAP_RSP(%rcx), %rsp # Restore stack pointer.
  150. jmp *TRAP_RIP(%rcx) # Return.
  151. END_FUNCTION(setcontext)
  152. //
  153. // __NO_RETURN
  154. // void
  155. // ClpContextStart (
  156. // void (*StartFunction)(),
  157. // ...
  158. // )
  159. //
  160. /*++
  161. Routine Description:
  162. This routine is a small trampoline that calls the function specified in
  163. makecontext.
  164. Arguments:
  165. StartFunction - Supplies a pointer to the function to call.
  166. ... - Supplies the arguments the start function takes.
  167. Return Value:
  168. This routine does not return.
  169. --*/
  170. FUNCTION(ClpContextStart)
  171. int $3 # TODO: Check this, it's never been run!
  172. popq %rax # Get the function to call.
  173. popq %rdi # Pop argument 1.
  174. popq %rsi # Pop argument 2.
  175. popq %rdx # Pop argument 3.
  176. popq %rcx # Pop argument 4.
  177. popq %r8 # Pop argument 5.
  178. popq %r9 # Pop argument 6.
  179. callq *%rax # Make it rain.
  180. movq %r12, %rsp # Pop the function and all arguments off.
  181. call ClpContextEnd # Call the C helper to switch contexts.
  182. hlt # Execution should never reach here.
  183. END_FUNCTION(ClpContextStart)
  184. //
  185. // VOID
  186. // ClpFxSave (
  187. // PFPU_CONTEXT Buffer
  188. // )
  189. //
  190. /*++
  191. Routine Description:
  192. This routine saves the current x87 FPU, MMX, XMM, and MXCSR registers to a
  193. 512 byte memory location.
  194. Arguments:
  195. Buffer - Supplies a pointer to the buffer where the information will be
  196. saved. This buffer must be 16-byte aligned.
  197. Return Value:
  198. None.
  199. --*/
  200. FUNCTION(ClpFxSave)
  201. fxsave (%rdi) # Save the state into there.
  202. ret
  203. END_FUNCTION(ClpFxSave)
  204. //
  205. // VOID
  206. // ClpFxRestore (
  207. // PFPU_CONTEXT Buffer
  208. // )
  209. //
  210. /*++
  211. Routine Description:
  212. This routine restores the current x87 FPU, MMX, XMM, and MXCSR registers
  213. from a 512 byte memory location.
  214. Arguments:
  215. Buffer - Supplies a pointer to the buffer where the information will be
  216. loaded from. This buffer must be 16-byte aligned.
  217. Return Value:
  218. None.
  219. --*/
  220. FUNCTION(ClpFxRestore)
  221. fxrstor (%rdi) # Load the state from there.
  222. ret
  223. END_FUNCTION(ClpFxRestore)