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