Home | History | Annotate | Download | only in x86
      1 /* -----------------------------------------------------------------------
      2    sysv.S - Copyright (c) 1996, 1998, 2001-2003, 2005, 2008  Red Hat, Inc.
      3 
      4    X86 Foreign Function Interface
      5 
      6    Permission is hereby granted, free of charge, to any person obtaining
      7    a copy of this software and associated documentation files (the
      8    ``Software''), to deal in the Software without restriction, including
      9    without limitation the rights to use, copy, modify, merge, publish,
     10    distribute, sublicense, and/or sell copies of the Software, and to
     11    permit persons to whom the Software is furnished to do so, subject to
     12    the following conditions:
     13 
     14    The above copyright notice and this permission notice shall be included
     15    in all copies or substantial portions of the Software.
     16 
     17    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
     18    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     20    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     21    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     22    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     23    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     24    DEALINGS IN THE SOFTWARE.
     25    ----------------------------------------------------------------------- */
     26 
     27 #ifndef __x86_64__
     28 
     29 #define LIBFFI_ASM
     30 #include <fficonfig.h>
     31 #include <ffi.h>
     32 
     33 .text
     34 
     35 .globl ffi_prep_args
     36 
     37 	.align 4
     38 .globl ffi_call_SYSV
     39         .type    ffi_call_SYSV,@function
     40 
     41 ffi_call_SYSV:
     42 .LFB1:
     43         pushl %ebp
     44 .LCFI0:
     45         movl  %esp,%ebp
     46 .LCFI1:
     47 	subl $8,%esp    /* Android: copy from darwin.S */
     48 	/* Make room for all of the new args.  */
     49 	movl  16(%ebp),%ecx
     50 	subl  %ecx,%esp
     51 
     52 	movl  %esp,%eax
     53 
     54 	/* Place all of the ffi_prep_args in position  */
     55 	subl  $8,%esp	/* Android: copy from darwin.S */
     56 	pushl 12(%ebp)
     57 	pushl %eax
     58 	call  *8(%ebp)
     59 
     60 	/* Return stack to previous state and call the function  */
     61 	addl  $16,%esp	/* Android: copy from darwin.S */
     62 
     63 	call  *28(%ebp)
     64 
     65 	/* Load %ecx with the return type code  */
     66 	movl  20(%ebp),%ecx
     67 
     68 	/* Protect %esi.  We're going to pop it in the epilogue.  */
     69 	pushl %esi
     70 
     71 	/* If the return value pointer is NULL, assume no return value.  */
     72 	cmpl  $0,24(%ebp)
     73 	jne  0f
     74 
     75 	/* Even if there is no space for the return value, we are
     76 	   obliged to handle floating-point values.  */
     77 	cmpl  $FFI_TYPE_FLOAT,%ecx
     78 	jne   noretval
     79 	fstp  %st(0)
     80 
     81         jmp   epilogue
     82 
     83 0:
     84 	call  1f
     85 
     86 .Lstore_table:
     87 	.long	noretval-.Lstore_table	/* FFI_TYPE_VOID */
     88 	.long	retint-.Lstore_table	/* FFI_TYPE_INT */
     89 	.long	retfloat-.Lstore_table	/* FFI_TYPE_FLOAT */
     90 	.long	retdouble-.Lstore_table	/* FFI_TYPE_DOUBLE */
     91 	.long	retlongdouble-.Lstore_table	/* FFI_TYPE_LONGDOUBLE */
     92 	.long	retuint8-.Lstore_table	/* FFI_TYPE_UINT8 */
     93 	.long	retsint8-.Lstore_table	/* FFI_TYPE_SINT8 */
     94 	.long	retuint16-.Lstore_table	/* FFI_TYPE_UINT16 */
     95 	.long	retsint16-.Lstore_table	/* FFI_TYPE_SINT16 */
     96 	.long	retint-.Lstore_table	/* FFI_TYPE_UINT32 */
     97 	.long	retint-.Lstore_table	/* FFI_TYPE_SINT32 */
     98 	.long	retint64-.Lstore_table	/* FFI_TYPE_UINT64 */
     99 	.long	retint64-.Lstore_table	/* FFI_TYPE_SINT64 */
    100 	.long	retstruct-.Lstore_table	/* FFI_TYPE_STRUCT */
    101 	.long	retint-.Lstore_table	/* FFI_TYPE_POINTER */
    102 
    103 1:
    104 	pop  %esi
    105 	add  (%esi, %ecx, 4), %esi
    106 	jmp  *%esi
    107 
    108 	/* Sign/zero extend as appropriate.  */
    109 retsint8:
    110 	movsbl  %al, %eax
    111 	jmp  retint
    112 
    113 retsint16:
    114 	movswl  %ax, %eax
    115 	jmp  retint
    116 
    117 retuint8:
    118 	movzbl  %al, %eax
    119 	jmp  retint
    120 
    121 retuint16:
    122 	movzwl  %ax, %eax
    123 	jmp  retint
    124 
    125 retfloat:
    126 	/* Load %ecx with the pointer to storage for the return value  */
    127 	movl  24(%ebp),%ecx
    128 	fstps (%ecx)
    129 	jmp   epilogue
    130 
    131 retdouble:
    132 	/* Load %ecx with the pointer to storage for the return value  */
    133 	movl  24(%ebp),%ecx
    134 	fstpl (%ecx)
    135 	jmp   epilogue
    136 
    137 retlongdouble:
    138 	/* Load %ecx with the pointer to storage for the return value  */
    139 	movl  24(%ebp),%ecx
    140 	fstpt (%ecx)
    141 	jmp   epilogue
    142 
    143 retint64:
    144 	/* Load %ecx with the pointer to storage for the return value  */
    145 	movl  24(%ebp),%ecx
    146 	movl  %eax,0(%ecx)
    147 	movl  %edx,4(%ecx)
    148 	jmp   epilogue
    149 
    150 retint:
    151 	/* Load %ecx with the pointer to storage for the return value  */
    152 	movl  24(%ebp),%ecx
    153 	movl  %eax,0(%ecx)
    154 
    155 retstruct:
    156 	/* Nothing to do!  */
    157 
    158 noretval:
    159 epilogue:
    160         popl %esi
    161         movl %ebp,%esp
    162         popl %ebp
    163         ret
    164 .LFE1:
    165 .ffi_call_SYSV_end:
    166         .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
    167 
    168 	.align	4
    169 FFI_HIDDEN (ffi_closure_SYSV)
    170 .globl ffi_closure_SYSV
    171 	.type	ffi_closure_SYSV, @function
    172 
    173 ffi_closure_SYSV:
    174 .LFB2:
    175 	pushl	%ebp
    176 .LCFI2:
    177 	movl	%esp, %ebp
    178 .LCFI3:
    179 	subl	$40, %esp
    180 	leal	-24(%ebp), %edx
    181 	movl	%edx, -12(%ebp)	/* resp */
    182 	leal	8(%ebp), %edx
    183 	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
    184 	leal	-12(%ebp), %edx
    185 	movl	%edx, (%esp)	/* &resp */
    186 #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
    187 	call	ffi_closure_SYSV_inner
    188 #else
    189 	movl	%ebx, 8(%esp)
    190 .LCFI7:
    191 	call	1f
    192 1:	popl	%ebx
    193 	addl	$_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
    194 	call	ffi_closure_SYSV_inner@PLT
    195 	movl	8(%esp), %ebx
    196 #endif
    197 	movl	-12(%ebp), %ecx
    198 	cmpl	$FFI_TYPE_INT, %eax
    199 	je	.Lcls_retint
    200 
    201 	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
    202 	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
    203 	cmpl	$FFI_TYPE_UINT64, %eax
    204 	jge	0f
    205 	cmpl	$FFI_TYPE_UINT8, %eax
    206 	jge	.Lcls_retint
    207 
    208 0:	cmpl	$FFI_TYPE_FLOAT, %eax
    209 	je	.Lcls_retfloat
    210 	cmpl	$FFI_TYPE_DOUBLE, %eax
    211 	je	.Lcls_retdouble
    212 	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
    213 	je	.Lcls_retldouble
    214 	cmpl	$FFI_TYPE_SINT64, %eax
    215 	je	.Lcls_retllong
    216 	cmpl	$FFI_TYPE_STRUCT, %eax
    217 	je	.Lcls_retstruct
    218 .Lcls_epilogue:
    219 	movl	%ebp, %esp
    220 	popl	%ebp
    221 	ret
    222 .Lcls_retint:
    223 	movl	(%ecx), %eax
    224 	jmp	.Lcls_epilogue
    225 .Lcls_retfloat:
    226 	flds	(%ecx)
    227 	jmp	.Lcls_epilogue
    228 .Lcls_retdouble:
    229 	fldl	(%ecx)
    230 	jmp	.Lcls_epilogue
    231 .Lcls_retldouble:
    232 	fldt	(%ecx)
    233 	jmp	.Lcls_epilogue
    234 .Lcls_retllong:
    235 	movl	(%ecx), %eax
    236 	movl	4(%ecx), %edx
    237 	jmp	.Lcls_epilogue
    238 .Lcls_retstruct:
    239 	movl	%ebp, %esp
    240 	popl	%ebp
    241 	ret	$4
    242 .LFE2:
    243 	.size	ffi_closure_SYSV, .-ffi_closure_SYSV
    244 
    245 #if !FFI_NO_RAW_API
    246 
    247 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
    248 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
    249 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
    250 #define CIF_FLAGS_OFFSET 20
    251 
    252 	.align	4
    253 FFI_HIDDEN (ffi_closure_raw_SYSV)
    254 .globl ffi_closure_raw_SYSV
    255 	.type	ffi_closure_raw_SYSV, @function
    256 
    257 ffi_closure_raw_SYSV:
    258 .LFB3:
    259 	pushl	%ebp
    260 .LCFI4:
    261 	movl	%esp, %ebp
    262 .LCFI5:
    263 	pushl	%esi
    264 .LCFI6:
    265 	subl	$36, %esp
    266 	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
    267 	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
    268 	movl	%edx, 12(%esp)	/* user_data */
    269 	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
    270 	movl	%edx, 8(%esp)	/* raw_args */
    271 	leal	-24(%ebp), %edx
    272 	movl	%edx, 4(%esp)	/* &res */
    273 	movl	%esi, (%esp)	/* cif */
    274 	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
    275 	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
    276 	cmpl	$FFI_TYPE_INT, %eax
    277 	je	.Lrcls_retint
    278 
    279 	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
    280 	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
    281 	cmpl	$FFI_TYPE_UINT64, %eax
    282 	jge	0f
    283 	cmpl	$FFI_TYPE_UINT8, %eax
    284 	jge	.Lrcls_retint
    285 0:
    286 	cmpl	$FFI_TYPE_FLOAT, %eax
    287 	je	.Lrcls_retfloat
    288 	cmpl	$FFI_TYPE_DOUBLE, %eax
    289 	je	.Lrcls_retdouble
    290 	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
    291 	je	.Lrcls_retldouble
    292 	cmpl	$FFI_TYPE_SINT64, %eax
    293 	je	.Lrcls_retllong
    294 .Lrcls_epilogue:
    295 	addl	$36, %esp
    296 	popl	%esi
    297 	popl	%ebp
    298 	ret
    299 .Lrcls_retint:
    300 	movl	-24(%ebp), %eax
    301 	jmp	.Lrcls_epilogue
    302 .Lrcls_retfloat:
    303 	flds	-24(%ebp)
    304 	jmp	.Lrcls_epilogue
    305 .Lrcls_retdouble:
    306 	fldl	-24(%ebp)
    307 	jmp	.Lrcls_epilogue
    308 .Lrcls_retldouble:
    309 	fldt	-24(%ebp)
    310 	jmp	.Lrcls_epilogue
    311 .Lrcls_retllong:
    312 	movl	-24(%ebp), %eax
    313 	movl	-20(%ebp), %edx
    314 	jmp	.Lrcls_epilogue
    315 .LFE3:
    316 	.size	ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
    317 #endif
    318 
    319 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
    320 .Lframe1:
    321 	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
    322 .LSCIE1:
    323 	.long	0x0	/* CIE Identifier Tag */
    324 	.byte	0x1	/* CIE Version */
    325 #ifdef __PIC__
    326 	.ascii "zR\0"	/* CIE Augmentation */
    327 #else
    328 	.ascii "\0"	/* CIE Augmentation */
    329 #endif
    330 	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
    331 	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
    332 	.byte	0x8	/* CIE RA Column */
    333 #ifdef __PIC__
    334 	.byte	0x1	/* .uleb128 0x1; Augmentation size */
    335 	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
    336 #endif
    337 	.byte	0xc	/* DW_CFA_def_cfa */
    338 	.byte	0x4	/* .uleb128 0x4 */
    339 	.byte	0x4	/* .uleb128 0x4 */
    340 	.byte	0x88	/* DW_CFA_offset, column 0x8 */
    341 	.byte	0x1	/* .uleb128 0x1 */
    342 	.align 4
    343 .LECIE1:
    344 .LSFDE1:
    345 	.long	.LEFDE1-.LASFDE1	/* FDE Length */
    346 .LASFDE1:
    347 	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
    348 #ifdef __PIC__
    349 	.long	.LFB1-.	/* FDE initial location */
    350 #else
    351 	.long	.LFB1	/* FDE initial location */
    352 #endif
    353 	.long	.LFE1-.LFB1	/* FDE address range */
    354 #ifdef __PIC__
    355 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    356 #endif
    357 	.byte	0x4	/* DW_CFA_advance_loc4 */
    358 	.long	.LCFI0-.LFB1
    359 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    360 	.byte	0x8	/* .uleb128 0x8 */
    361 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    362 	.byte	0x2	/* .uleb128 0x2 */
    363 	.byte	0x4	/* DW_CFA_advance_loc4 */
    364 	.long	.LCFI1-.LCFI0
    365 	.byte	0xd	/* DW_CFA_def_cfa_register */
    366 	.byte	0x5	/* .uleb128 0x5 */
    367 	.align 4
    368 .LEFDE1:
    369 .LSFDE2:
    370 	.long	.LEFDE2-.LASFDE2	/* FDE Length */
    371 .LASFDE2:
    372 	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
    373 #ifdef __PIC__
    374 	.long	.LFB2-.	/* FDE initial location */
    375 #else
    376 	.long	.LFB2
    377 #endif
    378 	.long	.LFE2-.LFB2	/* FDE address range */
    379 #ifdef __PIC__
    380 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    381 #endif
    382 	.byte	0x4	/* DW_CFA_advance_loc4 */
    383 	.long	.LCFI2-.LFB2
    384 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    385 	.byte	0x8	/* .uleb128 0x8 */
    386 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    387 	.byte	0x2	/* .uleb128 0x2 */
    388 	.byte	0x4	/* DW_CFA_advance_loc4 */
    389 	.long	.LCFI3-.LCFI2
    390 	.byte	0xd	/* DW_CFA_def_cfa_register */
    391 	.byte	0x5	/* .uleb128 0x5 */
    392 #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
    393 	.byte	0x4	/* DW_CFA_advance_loc4 */
    394 	.long	.LCFI7-.LCFI3
    395 	.byte	0x83	/* DW_CFA_offset, column 0x3 */
    396 	.byte	0xa	/* .uleb128 0xa */
    397 #endif
    398 	.align 4
    399 .LEFDE2:
    400 
    401 #if !FFI_NO_RAW_API
    402 
    403 .LSFDE3:
    404 	.long	.LEFDE3-.LASFDE3	/* FDE Length */
    405 .LASFDE3:
    406 	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
    407 #ifdef __PIC__
    408 	.long	.LFB3-.	/* FDE initial location */
    409 #else
    410 	.long	.LFB3
    411 #endif
    412 	.long	.LFE3-.LFB3	/* FDE address range */
    413 #ifdef __PIC__
    414 	.byte	0x0	/* .uleb128 0x0; Augmentation size */
    415 #endif
    416 	.byte	0x4	/* DW_CFA_advance_loc4 */
    417 	.long	.LCFI4-.LFB3
    418 	.byte	0xe	/* DW_CFA_def_cfa_offset */
    419 	.byte	0x8	/* .uleb128 0x8 */
    420 	.byte	0x85	/* DW_CFA_offset, column 0x5 */
    421 	.byte	0x2	/* .uleb128 0x2 */
    422 	.byte	0x4	/* DW_CFA_advance_loc4 */
    423 	.long	.LCFI5-.LCFI4
    424 	.byte	0xd	/* DW_CFA_def_cfa_register */
    425 	.byte	0x5	/* .uleb128 0x5 */
    426 	.byte	0x4	/* DW_CFA_advance_loc4 */
    427 	.long	.LCFI6-.LCFI5
    428 	.byte	0x86	/* DW_CFA_offset, column 0x6 */
    429 	.byte	0x3	/* .uleb128 0x3 */
    430 	.align 4
    431 .LEFDE3:
    432 
    433 #endif
    434 
    435 #endif /* ifndef __x86_64__ */
    436 
    437 #if defined __ELF__ && defined __linux__
    438 	.section	.note.GNU-stack,"",@progbits
    439 #endif
    440