enter_enclave.S 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "enter_enclave.h"
  32. /* int __morestack(const tcs_t *tcs, const int fn, const void *ocall_table, const void *ms, CTrustThread *trust_thread); */
  33. .file "enter_enclave.S"
  34. .text
  35. DECLARE_GLOBAL_FUNC __morestack
  36. __morestack:
  37. EENTER_PROLOG
  38. movl frame_arg1, %edi /* fn */
  39. #if defined(__x86_64__)
  40. /* we defined fn as int, so we do sign extend.*/
  41. movslq %edi, %rdi
  42. #endif
  43. mov frame_arg3, %xsi /* ms */
  44. .Ldo_eenter:
  45. mov frame_arg0, %xbx /* tcs addr */
  46. lea_pic .Lasync_exit_pointer, %xcx /* aep addr */
  47. mov $SE_EENTER, %xax /* EENTER leaf */
  48. .Leenter_inst:
  49. ENCLU
  50. /*
  51. * at this point, we may have returned due to a normal EEXIT,
  52. * or we may have returned due to an OCALL. We differentiate
  53. * by popping the top of the stack. If it is not -1, we have
  54. * an untrusted bridge to call at that address.
  55. */
  56. /* We have an ocall. Call our bridge function. */
  57. cmp $OCMD_ERET, %xdi
  58. je .Leret
  59. .Ldo_ocall:
  60. /* call ocall
  61. * int ocall(const unsigned int proc, void *ocall_table, const void *ms, CEnclave *enclave);
  62. *
  63. * When EEXIT'ed from tRTS due to an OCALL,
  64. * - `rdi' holds OCALL index
  65. *- `rsi' holds the pointer to marshalling structure
  66. */
  67. .type sgx_ocall,@function
  68. .hidden sgx_ocall
  69. #if defined(__i386__)
  70. sub $(3*SE_WORDSIZE), %xsp /* make stack 16 bytes aligned */
  71. push frame_arg0
  72. push frame_arg4
  73. push %esi
  74. push frame_arg2
  75. push %edi
  76. #endif
  77. #if defined(__x86_64__)
  78. mov %rsi, %rdx /* param2 */
  79. /*mov %rdi, %rdi */ /* param0 */
  80. mov frame_arg2, %rsi /* param1 */
  81. mov frame_arg4, %rcx /* param3 */
  82. mov frame_arg0, %r8 /* param4 */
  83. #endif
  84. call stack_sticker
  85. cmp $SE_ERROR_READ_LOCK_FAIL, %eax
  86. je .Loret
  87. mov $ECMD_ORET, %xdi /* oret */
  88. mov %xax, %xsi /* the result of ocall */
  89. jmp .Ldo_eenter
  90. /* never return here */
  91. ud2
  92. .Leret:
  93. mov %xsi, %xax
  94. .Loret:
  95. EENTER_EPILOG
  96. .Lasync_exit_pointer:
  97. ENCLU
  98. .size __morestack, .-__morestack
  99. DECLARE_GLOBAL_FUNC get_aep
  100. lea_pic .Lasync_exit_pointer, %xax
  101. ret
  102. DECLARE_GLOBAL_FUNC get_eenterp
  103. lea_pic .Leenter_inst, %xax
  104. ret
  105. DECLARE_GLOBAL_FUNC get_eretp
  106. lea_pic .Leret, %xax
  107. ret
  108. /*
  109. * function stack_sticker is the wrapper of ocall,
  110. * before call ocall, update the ret address and frame pointer (BP) on the stack
  111. *
  112. * Stack before:
  113. * |__morestack stack |<--|
  114. * ------------- |
  115. * |return adress | |
  116. * xbp -> | caller xbp | --|
  117. * | |
  118. * xsp -> | |
  119. * -------------
  120. *
  121. * Stack after:
  122. * |__morestack stack |
  123. * ------------------
  124. * | __morestack(inside)|
  125. * xbp -> | xbp_t | ---->the frame point of __morestack
  126. * | |
  127. * xsp -> | |
  128. * | <ecall> |
  129. * ------------------
  130. * int stack_sticker(unsigned int proc, sgx_ocall_table_t *ocall_table, void *ms, CTrustThread *trust_thread, tcs_t *tcs)
  131. */
  132. DECLARE_GLOBAL_FUNC stack_sticker
  133. .hidden stack_sticker
  134. .type push_ocall_frame,@function
  135. .hidden push_ocall_frame
  136. .type pop_ocall_frame,@function
  137. .hidden pop_ocall_frame
  138. .cfi_startproc
  139. push %xbp
  140. .cfi_def_cfa_offset 2*SE_WORDSIZE
  141. .cfi_offset xbp,-2*SE_WORDSIZE
  142. mov %xsp, %xbp
  143. .cfi_def_cfa_register xbp
  144. #if defined(__i386__)
  145. sub $(10*SE_WORDSIZE), %xsp /* We should have the stack 16 bytes aligned */
  146. #elif defined(__x86_64__)
  147. sub $(10*SE_WORDSIZE), %xsp
  148. #endif
  149. /* save the return address and the frame point */
  150. mov (0*SE_WORDSIZE)(%xbp), %xax
  151. mov %xax, (4*SE_WORDSIZE)(%xsp)
  152. mov (1*SE_WORDSIZE)(%xbp), %xax
  153. mov %xax, (5*SE_WORDSIZE)(%xsp)
  154. #if defined(__i386__)
  155. /* save the first 4 parameters */
  156. mov frame_arg0, %xax
  157. mov %xax, (0*SE_WORDSIZE)(%xsp)
  158. mov frame_arg1, %xax
  159. mov %xax, (1*SE_WORDSIZE)(%xsp)
  160. mov frame_arg2, %xax
  161. mov %xax, (2*SE_WORDSIZE)(%xsp)
  162. mov frame_arg3, %xax
  163. mov %xax, (3*SE_WORDSIZE)(%xsp)
  164. /* update the frame infomation */
  165. mov frame_arg3, %xax /* the pointer of trustthread instance */
  166. push %xax
  167. mov frame_arg4, %xax /* tcs */
  168. push %xax
  169. push %xbp
  170. /*just for call push_ocall_frame and return, no stack 16 bytes alignment needed */
  171. call push_ocall_frame
  172. /* recover parameters */
  173. add $(3*SE_WORDSIZE), %xsp
  174. #elif defined(__x86_64__)
  175. /* save the first 4 parameters */
  176. mov %xdi, (0*SE_WORDSIZE)(%xsp)
  177. mov %xsi, (1*SE_WORDSIZE)(%xsp)
  178. mov %xdx, (2*SE_WORDSIZE)(%xsp)
  179. mov %xcx, (3*SE_WORDSIZE)(%xsp)
  180. /* update the frame infomation */
  181. mov %xcx, %xdx /* the pointer of trustthread instance */
  182. mov %r8, %xsi /* tcs */
  183. mov %xbp, %xdi
  184. call push_ocall_frame
  185. /* recover parameters */
  186. mov (0*SE_WORDSIZE)(%xsp), %xdi
  187. mov (1*SE_WORDSIZE)(%xsp), %xsi
  188. mov (2*SE_WORDSIZE)(%xsp), %xdx
  189. mov (3*SE_WORDSIZE)(%xsp), %xcx
  190. #endif
  191. /* start the ocall */
  192. call sgx_ocall
  193. /* save the return value */
  194. mov %xax, (0*SE_WORDSIZE)(%xsp)
  195. #if defined(__i386__)
  196. /* pop the frame infomation */
  197. mov frame_arg3, %xax /* the pointer of trustthread instance */
  198. push %xax
  199. mov frame_arg4, %xax /* tcs is not used for now */
  200. push %xax
  201. call pop_ocall_frame
  202. /* recover parameters */
  203. add $(2*SE_WORDSIZE), %xsp
  204. #elif defined(__x86_64__)
  205. /* pop the frame infomation */
  206. mov (3*SE_WORDSIZE)(%xsp), %xsi /* the pointer of trustthread instance */
  207. call pop_ocall_frame
  208. #endif
  209. /* recover the return address and frame point */
  210. mov (4*SE_WORDSIZE)(%xsp), %xax
  211. mov %xax, (0*SE_WORDSIZE)(%xbp)
  212. mov (5*SE_WORDSIZE)(%xsp), %xax
  213. mov %xax, (1*SE_WORDSIZE)(%xbp)
  214. /* recover the return value */
  215. mov (0*SE_WORDSIZE)(%xsp), %xax
  216. leave
  217. ret
  218. .cfi_endproc
  219. /*
  220. * void sgx_debug_load_state_add_element(debug_enclave_info_t* new_enclave_info, debug_enclave_info_t** g_debug_enclave_info_list)
  221. * On x86, calling convention is "void sgx_debug_load_state_add_element(eax, edx)"
  222. * On x64, calling convention is "void sgx_debug_load_state_add_element(rdi, rsi)"
  223. * Add an new enclave info to list head and raise enclave load event
  224. */
  225. DECLARE_GLOBAL_FUNC sgx_debug_load_state_add_element
  226. #if defined(__i386__)
  227. movl %eax, (%edx)
  228. #else
  229. movq %rdi, (%rsi)
  230. #endif
  231. ret
  232. /*
  233. * void sgx_debug_unload_state_remove_element(debug_enclave_info_t* enclave_info, debug_enclave_info_t** pre_enclave_info, debug_enclave_info_t* next_enclave_info)
  234. * On x86, calling convention is "void se_debug_load_state_remove_element(eax, edx, ecx)"
  235. * On x64, calling convention is "void se_debug_load_state_remove_element(rdi, rsi, rdx)"
  236. * eax is to pass the removed enclave info to debugger.
  237. * Remove an enclave info from list and raise enclave unload event
  238. */
  239. DECLARE_GLOBAL_FUNC sgx_debug_unload_state_remove_element
  240. #if defined(__i386__)
  241. movl %ecx, (%edx)
  242. #else
  243. movq %rdx, (%rsi)
  244. #endif
  245. ret
  246. /* We do not need executable stack.*/
  247. .section .note.GNU-stack,"",@progbits