123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /*
- * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #include "enter_enclave.h"
- /* int __morestack(const tcs_t *tcs, const int fn, const void *ocall_table, const void *ms, CTrustThread *trust_thread); */
- .file "enter_enclave.S"
- .text
- DECLARE_GLOBAL_FUNC __morestack
- __morestack:
- EENTER_PROLOG
- movl frame_arg1, %edi /* fn */
- #if defined(__x86_64__)
- /* we defined fn as int, so we do sign extend.*/
- movslq %edi, %rdi
- #endif
- mov frame_arg3, %xsi /* ms */
- .Ldo_eenter:
- mov frame_arg0, %xbx /* tcs addr */
- lea_pic .Lasync_exit_pointer, %xcx /* aep addr */
- mov $SE_EENTER, %xax /* EENTER leaf */
- .Leenter_inst:
- ENCLU
- /*
- * at this point, we may have returned due to a normal EEXIT,
- * or we may have returned due to an OCALL. We differentiate
- * by popping the top of the stack. If it is not OCMD_ERET, we have
- * an untrusted bridge to call at that address.
- */
- /* We have an ocall. Call our bridge function. */
- cmp $OCMD_ERET, %xdi
- je .Leret
- .Ldo_ocall:
- /* call ocall
- * int ocall(const unsigned int proc, void *ocall_table, const void *ms, CEnclave *enclave);
- *
- * When EEXIT'ed from tRTS due to an OCALL,
- * - `rdi' holds OCALL index
- *- `rsi' holds the pointer to marshalling structure
- */
- .type sgx_ocall,@function
- .hidden sgx_ocall
- #if defined(__i386__)
- sub $(3*SE_WORDSIZE), %xsp /* make stack 16 bytes aligned */
- push frame_arg0
- push frame_arg4
- push %esi
- push frame_arg2
- push %edi
- #endif
- #if defined(__x86_64__)
- mov %rsi, %rdx /* param2 */
- /*mov %rdi, %rdi */ /* param0 */
- mov frame_arg2, %rsi /* param1 */
- mov frame_arg4, %rcx /* param3 */
- mov frame_arg0, %r8 /* param4 */
- #endif
- call stack_sticker
- cmp $SE_ERROR_READ_LOCK_FAIL, %eax
- je .Loret
- mov $ECMD_ORET, %xdi /* oret */
- mov %xax, %xsi /* the result of ocall */
- jmp .Ldo_eenter
- /* never return here */
- ud2
- .Leret:
- mov %xsi, %xax
- .Loret:
- EENTER_EPILOG
- .Lasync_exit_pointer:
- ENCLU
- .size __morestack, .-__morestack
- DECLARE_GLOBAL_FUNC get_aep
- lea_pic .Lasync_exit_pointer, %xax
- ret
- DECLARE_GLOBAL_FUNC get_eenterp
- lea_pic .Leenter_inst, %xax
- ret
- DECLARE_GLOBAL_FUNC get_eretp
- lea_pic .Leret, %xax
- ret
- /*
- * function stack_sticker is the wrapper of ocall,
- * before call ocall, update the ret address and frame pointer (BP) on the stack
- *
- * Stack before:
- * |__morestack stack |<--|
- * ------------- |
- * |return adress | |
- * xbp -> | caller xbp | --|
- * | |
- * xsp -> | |
- * -------------
- *
- * Stack after:
- * |__morestack stack |
- * ------------------
- * | __morestack(inside)|
- * xbp -> | xbp_t | ---->the frame point of __morestack
- * | |
- * xsp -> | |
- * | <ecall> |
- * ------------------
- * int stack_sticker(unsigned int proc, sgx_ocall_table_t *ocall_table, void *ms, CTrustThread *trust_thread, tcs_t *tcs)
- */
- DECLARE_GLOBAL_FUNC stack_sticker
- .hidden stack_sticker
- .type push_ocall_frame,@function
- .hidden push_ocall_frame
- .type pop_ocall_frame,@function
- .hidden pop_ocall_frame
- .cfi_startproc
- push %xbp
- .cfi_def_cfa_offset 2*SE_WORDSIZE
- .cfi_offset xbp,-2*SE_WORDSIZE
- mov %xsp, %xbp
- .cfi_def_cfa_register xbp
- #if defined(__i386__)
- sub $(10*SE_WORDSIZE), %xsp /* We should have the stack 16 bytes aligned */
- #elif defined(__x86_64__)
- sub $(10*SE_WORDSIZE), %xsp
- #endif
- /* save the return address and the frame point */
- mov (0*SE_WORDSIZE)(%xbp), %xax
- mov %xax, (4*SE_WORDSIZE)(%xsp)
- mov (1*SE_WORDSIZE)(%xbp), %xax
- mov %xax, (5*SE_WORDSIZE)(%xsp)
- #if defined(__i386__)
- /* save the first 4 parameters */
- mov frame_arg0, %xax
- mov %xax, (0*SE_WORDSIZE)(%xsp)
- mov frame_arg1, %xax
- mov %xax, (1*SE_WORDSIZE)(%xsp)
- mov frame_arg2, %xax
- mov %xax, (2*SE_WORDSIZE)(%xsp)
- mov frame_arg3, %xax
- mov %xax, (3*SE_WORDSIZE)(%xsp)
- /* update the frame infomation */
- mov frame_arg3, %xax /* the pointer of trustthread instance */
- push %xax
- mov frame_arg4, %xax /* tcs */
- push %xax
- push %xbp
- /*just for call push_ocall_frame and return, no stack 16 bytes alignment needed */
- call push_ocall_frame
- /* recover parameters */
- add $(3*SE_WORDSIZE), %xsp
- #elif defined(__x86_64__)
- /* save the first 4 parameters */
- mov %xdi, (0*SE_WORDSIZE)(%xsp)
- mov %xsi, (1*SE_WORDSIZE)(%xsp)
- mov %xdx, (2*SE_WORDSIZE)(%xsp)
- mov %xcx, (3*SE_WORDSIZE)(%xsp)
- /* update the frame infomation */
- mov %xcx, %xdx /* the pointer of trustthread instance */
- mov %r8, %xsi /* tcs */
- mov %xbp, %xdi
- call push_ocall_frame
- /* recover parameters */
- mov (0*SE_WORDSIZE)(%xsp), %xdi
- mov (1*SE_WORDSIZE)(%xsp), %xsi
- mov (2*SE_WORDSIZE)(%xsp), %xdx
- mov (3*SE_WORDSIZE)(%xsp), %xcx
- #endif
- /* start the ocall */
- call sgx_ocall
-
- /* save the return value */
- mov %xax, (0*SE_WORDSIZE)(%xsp)
- #if defined(__i386__)
- /* pop the frame infomation */
- mov frame_arg3, %xax /* the pointer of trustthread instance */
- push %xax
- mov frame_arg4, %xax /* tcs is not used for now */
- push %xax
- call pop_ocall_frame
- /* recover parameters */
- add $(2*SE_WORDSIZE), %xsp
-
- #elif defined(__x86_64__)
- /* pop the frame infomation */
- mov (3*SE_WORDSIZE)(%xsp), %xsi /* the pointer of trustthread instance */
- call pop_ocall_frame
- #endif
- /* recover the return address and frame point */
- mov (4*SE_WORDSIZE)(%xsp), %xax
- mov %xax, (0*SE_WORDSIZE)(%xbp)
- mov (5*SE_WORDSIZE)(%xsp), %xax
- mov %xax, (1*SE_WORDSIZE)(%xbp)
-
- /* recover the return value */
- mov (0*SE_WORDSIZE)(%xsp), %xax
- leave
- ret
- .cfi_endproc
- /*
- * void sgx_debug_load_state_add_element(debug_enclave_info_t* new_enclave_info, debug_enclave_info_t** g_debug_enclave_info_list)
- * On x86, calling convention is "void sgx_debug_load_state_add_element(eax, edx)"
- * On x64, calling convention is "void sgx_debug_load_state_add_element(rdi, rsi)"
- * Add an new enclave info to list head and raise enclave load event
- */
- DECLARE_GLOBAL_FUNC sgx_debug_load_state_add_element
- #if defined(__i386__)
- movl %eax, (%edx)
- #else
- movq %rdi, (%rsi)
- #endif
- ret
- /*
- * 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)
- * On x86, calling convention is "void se_debug_load_state_remove_element(eax, edx, ecx)"
- * On x64, calling convention is "void se_debug_load_state_remove_element(rdi, rsi, rdx)"
- * eax is to pass the removed enclave info to debugger.
- * Remove an enclave info from list and raise enclave unload event
- */
- DECLARE_GLOBAL_FUNC sgx_debug_unload_state_remove_element
- #if defined(__i386__)
- movl %ecx, (%edx)
- #else
- movq %rdx, (%rsi)
- #endif
- ret
- /* We do not need executable stack.*/
- .section .note.GNU-stack,"",@progbits
|