123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- /*
- * 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.
- *
- */
- /*
- * This header wraps the register names for x86/x64.
- */
- #ifndef LINUX_REGS_H__
- #define LINUX_REGS_H__
- #if defined(__i386) || defined(__i386__)
- # define LINUX32 1
- # define SE_WORDSIZE 4
- /* Generic argument picker for `naked' functions */
- # define naked_arg0 4(%esp)
- # define naked_arg1 8(%esp)
- # define naked_arg2 12(%esp)
- # define naked_arg3 16(%esp)
- # define xax eax
- # define xbx ebx
- # define xcx ecx
- # define xdx edx
- # define xsi esi
- # define xdi edi
- # define xbp ebp
- # define xsp esp
- #elif defined(__x86_64) || defined(__x86_64__)
- # define LINUX64 1
- # define SE_WORDSIZE 8
- /* For x86_64, the first six parameters are passed by
- * rdi, rsi, rdx, rcx, r8, r9.
- */
- # define naked_arg0 %rdi
- # define naked_arg1 %rsi
- # define naked_arg2 %rdx
- # define naked_arg3 %rcx
- # define xax rax
- # define xbx rbx
- # define xcx rcx
- # define xdx rdx
- # define xsi rsi
- # define xdi rdi
- # define xbp rbp
- # define xsp rsp
- #else
- # error unknown platform!
- #endif
- /* SE instructions - needs to be sync-up with inst70.h */
- #define SE_EREPORT 0
- #define SE_EGETKEY 1
- #define SE_EENTER 2
- #define SE_EEXIT 4
- #define SE_ECREATE 0
- #define SE_EADD 1
- #define SE_EINIT 2
- #define SE_EREMOVE 3
- /*
- * Macros for GNU assembly
- */
- .macro ENCLU
- #ifdef SE_SIM
- cmp $SE_EEXIT, %xax
- jne 1f
- /* if leaf is EEXIT, xbp and xsp need to be passed by xdx and xcx */
- mov %xbp, %xdx
- mov %xsp, %xcx
- 1:
- push %xdi
- push %xsi
- push %xdx
- push %xcx
- push %xbx
- push %xax
- # ifdef LINUX64
- pop %rdi
- pop %rsi
- pop %rdx
- pop %rcx
- pop %r8
- pop %r9
- # endif
- .type _SE3,@function
- .protected _SE3
- call _SE3
- # ifdef LINUX32
- add $(SE_WORDSIZE * 6), %esp
- # endif
- #else /* SE_SIM */
- .byte 0x0f, 0x01, 0xd7 /* 0xf3 */
- #endif /* !SE_SIM */
- .endm
- /* declare a function with default visibility */
- .macro DECLARE_GLOBAL_FUNC name
- .globl \name
- .type \name, @function
- \name:
- .endm
- /* declare a function with visibility='hidden' */
- .macro DECLARE_LOCAL_FUNC name
- .globl \name
- .hidden \name
- .type \name, @function
- \name:
- .endm
- .macro NAKED_PROLOG
- push %xbp
- mov %xsp, %xbp
- sub $(7 * SE_WORDSIZE), %xsp
- .endm
- .macro NAKED_EPILOG
- mov %xbp, %xsp
- pop %xbp
- .endm
- /* `paramN' (N = 1,2,3,4) should be registers. */
- .macro SET_PARAMS param1:req, param2, param3, param4
- #if defined(LINUX32)
- .ifnb \param4
- mov \param4, 3*SE_WORDSIZE(%esp)
- .endif
- .ifnb \param3
- mov \param3, 2*SE_WORDSIZE(%esp)
- .endif
- .ifnb \param2
- mov \param2, 1*SE_WORDSIZE(%esp)
- .endif
- mov \param1, 0*SE_WORDSIZE(%esp)
- #else /* LINUX32 */
- .ifnb \param4
- .ifnc \param4, %rcx
- mov \param4, %rcx
- .endif
- .endif
- .ifnb \param3
- .ifnc \param3, %rdx
- mov \param3, %rdx
- .endif
- .endif
- .ifnb \param2
- .ifnc \param2, %rsi
- mov \param2, %rsi
- .endif
- .endif
- .ifnc \param1, %rdi
- mov \param1, %rdi
- .endif
- #endif /* LINUX64 */
- .endm
- /*******************************************************************/
- .macro SE_PROLOG
- .cfi_startproc
- #ifdef LINUX32
- pushl %ebp
- movl %esp, %ebp
- #endif
- push %xbx
- push %xcx
- push %xdx
- #if defined LINUX64
- movq %rdi, %rbx
- movq %rsi, %rcx
- /* rdx remains the same, rdi/rsi is not used by _SE0
- */
- #elif defined LINUX32
- movl 2*SE_WORDSIZE(%ebp), %ebx
- movl 3*SE_WORDSIZE(%ebp), %ecx
- movl 4*SE_WORDSIZE(%ebp), %edx
- #endif
- .endm
- /*******************************************************************/
- .macro SE_EPILOG
- pop %xdx
- pop %xcx
- pop %xbx
- #ifdef LINUX32
- movl %ebp, %esp
- popl %ebp
- #endif
- ret
- .cfi_endproc
- .endm
- /*******************************************************************/
- /* load the address of `symbol' to the register `reg' in PIC way. */
- .macro lea_pic symbol, reg
- #ifdef LINUX64
- lea \symbol(%rip), \reg
- #else
- /* The real code on x86 would look like this (get `bar' from `foo'):
- *
- * 00000198 <bar>:
- * 198: c3 ret
- *
- * 00000199 <foo>:
- * 199: e8 00 00 00 00 call 19e <foo+0x5>
- * 19e: 58 pop %eax
- * 19f: 8d 40 fa lea -0x6(%eax),%eax
- */
- call . + 0x5 /* No label here to avoid interfering w/ calling code */
- pop \reg
- lea (\symbol - . + 1)(\reg), \reg
- #endif
- .endm
- #endif /* LINUX_REGS_H__ */
|