1 /* -----------------------------------------------------------------*-C-*- 2 libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green 3 - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. 4 5 Permission is hereby granted, free of charge, to any person 6 obtaining a copy of this software and associated documentation 7 files (the ``Software''), to deal in the Software without 8 restriction, including without limitation the rights to use, copy, 9 modify, merge, publish, distribute, sublicense, and/or sell copies 10 of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be 14 included in all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 DEALINGS IN THE SOFTWARE. 24 25 ----------------------------------------------------------------------- */ 26 27 /* ------------------------------------------------------------------- 28 Most of the API is documented in doc/libffi.texi. 29 30 The raw API is designed to bypass some of the argument packing and 31 unpacking on architectures for which it can be avoided. Routines 32 are provided to emulate the raw API if the underlying platform 33 doesn't allow faster implementation. 34 35 More details on the raw API can be found in: 36 37 http://gcc.gnu.org/ml/java/1999-q3/msg00138.html 38 39 and 40 41 http://gcc.gnu.org/ml/java/1999-q3/msg00174.html 42 -------------------------------------------------------------------- */ 43 44 #ifndef LIBFFI_H 45 #define LIBFFI_H 46 47 #ifdef __cplusplus 48 extern "C" { 49 #endif 50 51 /* Specify which architecture libffi is configured for. */ 52 #ifndef AARCH64 53 #define AARCH64 54 #endif 55 56 /* ---- System configuration information --------------------------------- */ 57 58 #include <ffitarget.h> 59 60 #ifndef LIBFFI_ASM 61 62 #if defined(_MSC_VER) && !defined(__clang__) 63 #define __attribute__(X) 64 #endif 65 66 #include <stddef.h> 67 #include <limits.h> 68 69 /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). 70 But we can find it either under the correct ANSI name, or under GNU 71 C's internal name. */ 72 73 #define FFI_64_BIT_MAX 9223372036854775807 74 75 #ifdef LONG_LONG_MAX 76 # define FFI_LONG_LONG_MAX LONG_LONG_MAX 77 #else 78 # ifdef LLONG_MAX 79 # define FFI_LONG_LONG_MAX LLONG_MAX 80 # ifdef _AIX52 /* or newer has C99 LLONG_MAX */ 81 # undef FFI_64_BIT_MAX 82 # define FFI_64_BIT_MAX 9223372036854775807LL 83 # endif /* _AIX52 or newer */ 84 # else 85 # ifdef __GNUC__ 86 # define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ 87 # endif 88 # ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */ 89 # ifndef __PPC64__ 90 # if defined (__IBMC__) || defined (__IBMCPP__) 91 # define FFI_LONG_LONG_MAX LONGLONG_MAX 92 # endif 93 # endif /* __PPC64__ */ 94 # undef FFI_64_BIT_MAX 95 # define FFI_64_BIT_MAX 9223372036854775807LL 96 # endif 97 # endif 98 #endif 99 100 /* The closure code assumes that this works on pointers, i.e. a size_t 101 can hold a pointer. */ 102 103 typedef struct _ffi_type 104 { 105 size_t size; 106 unsigned short alignment; 107 unsigned short type; 108 struct _ffi_type **elements; 109 } ffi_type; 110 111 /* Need minimal decorations for DLLs to work on Windows. GCC has 112 autoimport and autoexport. Always mark externally visible symbols 113 as dllimport for MSVC clients, even if it means an extra indirection 114 when using the static version of the library. 115 Besides, as a workaround, they can define FFI_BUILDING if they 116 *know* they are going to link with the static library. */ 117 #if defined _MSC_VER 118 # if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */ 119 # define FFI_API __declspec(dllexport) 120 # elif !defined FFI_BUILDING /* Importing libffi.DLL */ 121 # define FFI_API __declspec(dllimport) 122 # else /* Building/linking static library */ 123 # define FFI_API 124 # endif 125 #else 126 # define FFI_API 127 #endif 128 129 /* The externally visible type declarations also need the MSVC DLL 130 decorations, or they will not be exported from the object file. */ 131 #if defined LIBFFI_HIDE_BASIC_TYPES 132 # define FFI_EXTERN FFI_API 133 #else 134 # define FFI_EXTERN extern FFI_API 135 #endif 136 137 #ifndef LIBFFI_HIDE_BASIC_TYPES 138 #if SCHAR_MAX == 127 139 # define ffi_type_uchar ffi_type_uint8 140 # define ffi_type_schar ffi_type_sint8 141 #else 142 #error "char size not supported" 143 #endif 144 145 #if SHRT_MAX == 32767 146 # define ffi_type_ushort ffi_type_uint16 147 # define ffi_type_sshort ffi_type_sint16 148 #elif SHRT_MAX == 2147483647 149 # define ffi_type_ushort ffi_type_uint32 150 # define ffi_type_sshort ffi_type_sint32 151 #else 152 #error "short size not supported" 153 #endif 154 155 #if INT_MAX == 32767 156 # define ffi_type_uint ffi_type_uint16 157 # define ffi_type_sint ffi_type_sint16 158 #elif INT_MAX == 2147483647 159 # define ffi_type_uint ffi_type_uint32 160 # define ffi_type_sint ffi_type_sint32 161 #elif INT_MAX == 9223372036854775807 162 # define ffi_type_uint ffi_type_uint64 163 # define ffi_type_sint ffi_type_sint64 164 #else 165 #error "int size not supported" 166 #endif 167 168 #if LONG_MAX == 2147483647 169 # if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX 170 #error "no 64-bit data type supported" 171 # endif 172 #elif LONG_MAX != FFI_64_BIT_MAX 173 #error "long size not supported" 174 #endif 175 176 #if LONG_MAX == 2147483647 177 # define ffi_type_ulong ffi_type_uint32 178 # define ffi_type_slong ffi_type_sint32 179 #elif LONG_MAX == FFI_64_BIT_MAX 180 # define ffi_type_ulong ffi_type_uint64 181 # define ffi_type_slong ffi_type_sint64 182 #else 183 #error "long size not supported" 184 #endif 185 186 /* These are defined in types.c. */ 187 FFI_EXTERN ffi_type ffi_type_void; 188 FFI_EXTERN ffi_type ffi_type_uint8; 189 FFI_EXTERN ffi_type ffi_type_sint8; 190 FFI_EXTERN ffi_type ffi_type_uint16; 191 FFI_EXTERN ffi_type ffi_type_sint16; 192 FFI_EXTERN ffi_type ffi_type_uint32; 193 FFI_EXTERN ffi_type ffi_type_sint32; 194 FFI_EXTERN ffi_type ffi_type_uint64; 195 FFI_EXTERN ffi_type ffi_type_sint64; 196 FFI_EXTERN ffi_type ffi_type_float; 197 FFI_EXTERN ffi_type ffi_type_double; 198 FFI_EXTERN ffi_type ffi_type_pointer; 199 200 #ifndef _M_ARM64 201 FFI_EXTERN ffi_type ffi_type_longdouble; 202 #else 203 #define ffi_type_longdouble ffi_type_double 204 #endif 205 206 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE 207 FFI_EXTERN ffi_type ffi_type_complex_float; 208 FFI_EXTERN ffi_type ffi_type_complex_double; 209 #if 1 210 FFI_EXTERN ffi_type ffi_type_complex_longdouble; 211 #else 212 #define ffi_type_complex_longdouble ffi_type_complex_double 213 #endif 214 #endif 215 #endif /* LIBFFI_HIDE_BASIC_TYPES */ 216 217 typedef enum { 218 FFI_OK = 0, 219 FFI_BAD_TYPEDEF, 220 FFI_BAD_ABI 221 } ffi_status; 222 223 typedef struct { 224 ffi_abi abi; 225 unsigned nargs; 226 ffi_type **arg_types; 227 ffi_type *rtype; 228 unsigned bytes; 229 unsigned flags; 230 #ifdef FFI_EXTRA_CIF_FIELDS 231 FFI_EXTRA_CIF_FIELDS; 232 #endif 233 } ffi_cif; 234 235 /* ---- Definitions for the raw API -------------------------------------- */ 236 237 #ifndef FFI_SIZEOF_ARG 238 # if LONG_MAX == 2147483647 239 # define FFI_SIZEOF_ARG 4 240 # elif LONG_MAX == FFI_64_BIT_MAX 241 # define FFI_SIZEOF_ARG 8 242 # endif 243 #endif 244 245 #ifndef FFI_SIZEOF_JAVA_RAW 246 # define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG 247 #endif 248 249 typedef union { 250 ffi_sarg sint; 251 ffi_arg uint; 252 float flt; 253 char data[FFI_SIZEOF_ARG]; 254 void* ptr; 255 } ffi_raw; 256 257 #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8 258 /* This is a special case for mips64/n32 ABI (and perhaps others) where 259 sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */ 260 typedef union { 261 signed int sint; 262 unsigned int uint; 263 float flt; 264 char data[FFI_SIZEOF_JAVA_RAW]; 265 void* ptr; 266 } ffi_java_raw; 267 #else 268 typedef ffi_raw ffi_java_raw; 269 #endif 270 271 272 FFI_API 273 void ffi_raw_call (ffi_cif *cif, 274 void (*fn)(void), 275 void *rvalue, 276 ffi_raw *avalue); 277 278 FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); 279 FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); 280 FFI_API size_t ffi_raw_size (ffi_cif *cif); 281 282 /* This is analogous to the raw API, except it uses Java parameter 283 packing, even on 64-bit machines. I.e. on 64-bit machines longs 284 and doubles are followed by an empty 64-bit word. */ 285 286 FFI_API 287 void ffi_java_raw_call (ffi_cif *cif, 288 void (*fn)(void), 289 void *rvalue, 290 ffi_java_raw *avalue); 291 292 FFI_API 293 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); 294 FFI_API 295 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); 296 FFI_API 297 size_t ffi_java_raw_size (ffi_cif *cif); 298 299 /* ---- Definitions for closures ----------------------------------------- */ 300 301 #if FFI_CLOSURES 302 303 #ifdef _MSC_VER 304 __declspec(align(8)) 305 #endif 306 typedef struct { 307 #if 0 308 void *trampoline_table; 309 void *trampoline_table_entry; 310 #else 311 char tramp[FFI_TRAMPOLINE_SIZE]; 312 #endif 313 ffi_cif *cif; 314 void (*fun)(ffi_cif*,void*,void**,void*); 315 void *user_data; 316 } ffi_closure 317 #ifdef __GNUC__ 318 __attribute__((aligned (8))) 319 #endif 320 ; 321 322 #ifndef __GNUC__ 323 # ifdef __sgi 324 # pragma pack 0 325 # endif 326 #endif 327 328 FFI_API void *ffi_closure_alloc (size_t size, void **code); 329 FFI_API void ffi_closure_free (void *); 330 331 FFI_API ffi_status 332 ffi_prep_closure (ffi_closure*, 333 ffi_cif *, 334 void (*fun)(ffi_cif*,void*,void**,void*), 335 void *user_data) 336 #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405) 337 __attribute__((deprecated ("use ffi_prep_closure_loc instead"))) 338 #elif defined(__GNUC__) && __GNUC__ >= 3 339 __attribute__((deprecated)) 340 #endif 341 ; 342 343 FFI_API ffi_status 344 ffi_prep_closure_loc (ffi_closure*, 345 ffi_cif *, 346 void (*fun)(ffi_cif*,void*,void**,void*), 347 void *user_data, 348 void*codeloc); 349 350 #ifdef __sgi 351 # pragma pack 8 352 #endif 353 typedef struct { 354 #if 0 355 void *trampoline_table; 356 void *trampoline_table_entry; 357 #else 358 char tramp[FFI_TRAMPOLINE_SIZE]; 359 #endif 360 ffi_cif *cif; 361 362 #if !FFI_NATIVE_RAW_API 363 364 /* If this is enabled, then a raw closure has the same layout 365 as a regular closure. We use this to install an intermediate 366 handler to do the transaltion, void** -> ffi_raw*. */ 367 368 void (*translate_args)(ffi_cif*,void*,void**,void*); 369 void *this_closure; 370 371 #endif 372 373 void (*fun)(ffi_cif*,void*,ffi_raw*,void*); 374 void *user_data; 375 376 } ffi_raw_closure; 377 378 typedef struct { 379 #if 0 380 void *trampoline_table; 381 void *trampoline_table_entry; 382 #else 383 char tramp[FFI_TRAMPOLINE_SIZE]; 384 #endif 385 386 ffi_cif *cif; 387 388 #if !FFI_NATIVE_RAW_API 389 390 /* If this is enabled, then a raw closure has the same layout 391 as a regular closure. We use this to install an intermediate 392 handler to do the translation, void** -> ffi_raw*. */ 393 394 void (*translate_args)(ffi_cif*,void*,void**,void*); 395 void *this_closure; 396 397 #endif 398 399 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); 400 void *user_data; 401 402 } ffi_java_raw_closure; 403 404 FFI_API ffi_status 405 ffi_prep_raw_closure (ffi_raw_closure*, 406 ffi_cif *cif, 407 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 408 void *user_data); 409 410 FFI_API ffi_status 411 ffi_prep_raw_closure_loc (ffi_raw_closure*, 412 ffi_cif *cif, 413 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 414 void *user_data, 415 void *codeloc); 416 417 FFI_API ffi_status 418 ffi_prep_java_raw_closure (ffi_java_raw_closure*, 419 ffi_cif *cif, 420 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), 421 void *user_data); 422 423 FFI_API ffi_status 424 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, 425 ffi_cif *cif, 426 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), 427 void *user_data, 428 void *codeloc); 429 430 #endif /* FFI_CLOSURES */ 431 432 #if FFI_GO_CLOSURES 433 434 typedef struct { 435 void *tramp; 436 ffi_cif *cif; 437 void (*fun)(ffi_cif*,void*,void**,void*); 438 } ffi_go_closure; 439 440 FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *, 441 void (*fun)(ffi_cif*,void*,void**,void*)); 442 443 FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, 444 void **avalue, void *closure); 445 446 #endif /* FFI_GO_CLOSURES */ 447 448 /* ---- Public interface definition -------------------------------------- */ 449 450 FFI_API 451 ffi_status ffi_prep_cif(ffi_cif *cif, 452 ffi_abi abi, 453 unsigned int nargs, 454 ffi_type *rtype, 455 ffi_type **atypes); 456 457 FFI_API 458 ffi_status ffi_prep_cif_var(ffi_cif *cif, 459 ffi_abi abi, 460 unsigned int nfixedargs, 461 unsigned int ntotalargs, 462 ffi_type *rtype, 463 ffi_type **atypes); 464 465 FFI_API 466 void ffi_call(ffi_cif *cif, 467 void (*fn)(void), 468 void *rvalue, 469 void **avalue); 470 471 FFI_API 472 ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, 473 size_t *offsets); 474 475 /* Useful for eliminating compiler warnings. */ 476 #define FFI_FN(f) ((void (*)(void))f) 477 478 /* ---- Definitions shared with assembly code ---------------------------- */ 479 480 #endif 481 482 /* If these change, update src/mips/ffitarget.h. */ 483 #define FFI_TYPE_VOID 0 484 #define FFI_TYPE_INT 1 485 #define FFI_TYPE_FLOAT 2 486 #define FFI_TYPE_DOUBLE 3 487 #ifndef _M_ARM64 488 #define FFI_TYPE_LONGDOUBLE 4 489 #else 490 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE 491 #endif 492 #define FFI_TYPE_UINT8 5 493 #define FFI_TYPE_SINT8 6 494 #define FFI_TYPE_UINT16 7 495 #define FFI_TYPE_SINT16 8 496 #define FFI_TYPE_UINT32 9 497 #define FFI_TYPE_SINT32 10 498 #define FFI_TYPE_UINT64 11 499 #define FFI_TYPE_SINT64 12 500 #define FFI_TYPE_STRUCT 13 501 #define FFI_TYPE_POINTER 14 502 #define FFI_TYPE_COMPLEX 15 503 /* This should always refer to the last type code (for sanity checks). */ 504 #define FFI_TYPE_LAST FFI_TYPE_COMPLEX 505 506 507 #ifdef __cplusplus 508 } 509 #endif 510 511 #endif 512