1 /* -----------------------------------------------------------------*-C-*- 2 libffi 3.2.9999 - 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 ARM 53 #define ARM 54 #endif 55 56 /* ---- System configuration information --------------------------------- */ 57 58 #include <ffitarget.h> 59 60 /* Need minimal decorations for DLLs to works on Windows. GCC has 61 autoimport and autoexport. Rely on Libtool to help MSVC export 62 from a DLL, but always declare data to be imported for MSVC 63 clients. This costs an extra indirection for MSVC clients using 64 the static version of the library, but don't worry about that. 65 Besides, as a workaround, they can define FFI_BUILDING if they 66 *know* they are going to link with the static library. */ 67 #if defined _MSC_VER && !defined FFI_STATIC_BUILD 68 #ifdef FFI_BUILDING 69 #define FFI_EXTERN __declspec(dllexport) 70 #else 71 #define FFI_EXTERN __declspec(dllimport) 72 #endif 73 #else 74 #define FFI_EXTERN extern 75 #endif 76 77 #ifndef LIBFFI_ASM 78 79 #if defined(_MSC_VER) && !defined(__clang__) 80 #define __attribute__(X) 81 #endif 82 83 #include <stddef.h> 84 #include <limits.h> 85 86 /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). 87 But we can find it either under the correct ANSI name, or under GNU 88 C's internal name. */ 89 90 #define FFI_64_BIT_MAX 9223372036854775807 91 92 #ifdef LONG_LONG_MAX 93 # define FFI_LONG_LONG_MAX LONG_LONG_MAX 94 #else 95 # ifdef LLONG_MAX 96 # define FFI_LONG_LONG_MAX LLONG_MAX 97 # ifdef _AIX52 /* or newer has C99 LLONG_MAX */ 98 # undef FFI_64_BIT_MAX 99 # define FFI_64_BIT_MAX 9223372036854775807LL 100 # endif /* _AIX52 or newer */ 101 # else 102 # ifdef __GNUC__ 103 # define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ 104 # endif 105 # ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */ 106 # ifndef __PPC64__ 107 # if defined (__IBMC__) || defined (__IBMCPP__) 108 # define FFI_LONG_LONG_MAX LONGLONG_MAX 109 # endif 110 # endif /* __PPC64__ */ 111 # undef FFI_64_BIT_MAX 112 # define FFI_64_BIT_MAX 9223372036854775807LL 113 # endif 114 # endif 115 #endif 116 117 /* The closure code assumes that this works on pointers, i.e. a size_t 118 can hold a pointer. */ 119 120 typedef struct _ffi_type 121 { 122 size_t size; 123 unsigned short alignment; 124 unsigned short type; 125 struct _ffi_type **elements; 126 } ffi_type; 127 128 #ifndef LIBFFI_HIDE_BASIC_TYPES 129 #if SCHAR_MAX == 127 130 # define ffi_type_uchar ffi_type_uint8 131 # define ffi_type_schar ffi_type_sint8 132 #else 133 #error "char size not supported" 134 #endif 135 136 #if SHRT_MAX == 32767 137 # define ffi_type_ushort ffi_type_uint16 138 # define ffi_type_sshort ffi_type_sint16 139 #elif SHRT_MAX == 2147483647 140 # define ffi_type_ushort ffi_type_uint32 141 # define ffi_type_sshort ffi_type_sint32 142 #else 143 #error "short size not supported" 144 #endif 145 146 #if INT_MAX == 32767 147 # define ffi_type_uint ffi_type_uint16 148 # define ffi_type_sint ffi_type_sint16 149 #elif INT_MAX == 2147483647 150 # define ffi_type_uint ffi_type_uint32 151 # define ffi_type_sint ffi_type_sint32 152 #elif INT_MAX == 9223372036854775807 153 # define ffi_type_uint ffi_type_uint64 154 # define ffi_type_sint ffi_type_sint64 155 #else 156 #error "int size not supported" 157 #endif 158 159 #if LONG_MAX == 2147483647 160 # if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX 161 #error "no 64-bit data type supported" 162 # endif 163 #elif LONG_MAX != FFI_64_BIT_MAX 164 #error "long size not supported" 165 #endif 166 167 #if LONG_MAX == 2147483647 168 # define ffi_type_ulong ffi_type_uint32 169 # define ffi_type_slong ffi_type_sint32 170 #elif LONG_MAX == FFI_64_BIT_MAX 171 # define ffi_type_ulong ffi_type_uint64 172 # define ffi_type_slong ffi_type_sint64 173 #else 174 #error "long size not supported" 175 #endif 176 177 /* These are defined in types.c. */ 178 FFI_EXTERN ffi_type ffi_type_void; 179 FFI_EXTERN ffi_type ffi_type_uint8; 180 FFI_EXTERN ffi_type ffi_type_sint8; 181 FFI_EXTERN ffi_type ffi_type_uint16; 182 FFI_EXTERN ffi_type ffi_type_sint16; 183 FFI_EXTERN ffi_type ffi_type_uint32; 184 FFI_EXTERN ffi_type ffi_type_sint32; 185 FFI_EXTERN ffi_type ffi_type_uint64; 186 FFI_EXTERN ffi_type ffi_type_sint64; 187 FFI_EXTERN ffi_type ffi_type_float; 188 FFI_EXTERN ffi_type ffi_type_double; 189 FFI_EXTERN ffi_type ffi_type_pointer; 190 191 #if 0 192 FFI_EXTERN ffi_type ffi_type_longdouble; 193 #else 194 #define ffi_type_longdouble ffi_type_double 195 #endif 196 197 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE 198 FFI_EXTERN ffi_type ffi_type_complex_float; 199 FFI_EXTERN ffi_type ffi_type_complex_double; 200 #if 0 201 FFI_EXTERN ffi_type ffi_type_complex_longdouble; 202 #else 203 #define ffi_type_complex_longdouble ffi_type_complex_double 204 #endif 205 #endif 206 #endif /* LIBFFI_HIDE_BASIC_TYPES */ 207 208 typedef enum { 209 FFI_OK = 0, 210 FFI_BAD_TYPEDEF, 211 FFI_BAD_ABI 212 } ffi_status; 213 214 typedef struct { 215 ffi_abi abi; 216 unsigned nargs; 217 ffi_type **arg_types; 218 ffi_type *rtype; 219 unsigned bytes; 220 unsigned flags; 221 unsigned isVariadic; 222 #ifdef FFI_EXTRA_CIF_FIELDS 223 FFI_EXTRA_CIF_FIELDS; 224 #endif 225 } ffi_cif; 226 227 /* ---- Definitions for the raw API -------------------------------------- */ 228 229 #ifndef FFI_SIZEOF_ARG 230 # if LONG_MAX == 2147483647 231 # define FFI_SIZEOF_ARG 4 232 # elif LONG_MAX == FFI_64_BIT_MAX 233 # define FFI_SIZEOF_ARG 8 234 # endif 235 #endif 236 237 #ifndef FFI_SIZEOF_JAVA_RAW 238 # define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG 239 #endif 240 241 typedef union { 242 ffi_sarg sint; 243 ffi_arg uint; 244 float flt; 245 char data[FFI_SIZEOF_ARG]; 246 void* ptr; 247 } ffi_raw; 248 249 #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8 250 /* This is a special case for mips64/n32 ABI (and perhaps others) where 251 sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */ 252 typedef union { 253 signed int sint; 254 unsigned int uint; 255 float flt; 256 char data[FFI_SIZEOF_JAVA_RAW]; 257 void* ptr; 258 } ffi_java_raw; 259 #else 260 typedef ffi_raw ffi_java_raw; 261 #endif 262 263 FFI_EXTERN 264 void ffi_raw_call (ffi_cif *cif, 265 void (*fn)(void), 266 void *rvalue, 267 ffi_raw *avalue); 268 269 FFI_EXTERN void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); 270 FFI_EXTERN void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); 271 FFI_EXTERN size_t ffi_raw_size (ffi_cif *cif); 272 273 /* This is analogous to the raw API, except it uses Java parameter 274 packing, even on 64-bit machines. I.e. on 64-bit machines longs 275 and doubles are followed by an empty 64-bit word. */ 276 FFI_EXTERN 277 void ffi_java_raw_call (ffi_cif *cif, 278 void (*fn)(void), 279 void *rvalue, 280 ffi_java_raw *avalue); 281 282 FFI_EXTERN void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); 283 FFI_EXTERN void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); 284 FFI_EXTERN size_t ffi_java_raw_size (ffi_cif *cif); 285 286 /* ---- Definitions for closures ----------------------------------------- */ 287 288 #if FFI_CLOSURES 289 290 #ifdef _MSC_VER 291 __declspec(align(8)) 292 #endif 293 typedef struct { 294 #if 0 295 void *trampoline_table; 296 void *trampoline_table_entry; 297 #else 298 char tramp[FFI_TRAMPOLINE_SIZE]; 299 #endif 300 ffi_cif *cif; 301 void (*fun)(ffi_cif*,void*,void**,void*); 302 void *user_data; 303 } ffi_closure 304 #ifdef __GNUC__ 305 __attribute__((aligned (8))) 306 #endif 307 ; 308 309 #ifndef __GNUC__ 310 # ifdef __sgi 311 # pragma pack 0 312 # endif 313 #endif 314 315 FFI_EXTERN void *ffi_closure_alloc (size_t size, void **code); 316 FFI_EXTERN void ffi_closure_free (void *); 317 318 FFI_EXTERN ffi_status 319 ffi_prep_closure (ffi_closure*, 320 ffi_cif *, 321 void (*fun)(ffi_cif*,void*,void**,void*), 322 void *user_data) 323 #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405) 324 __attribute__((deprecated ("use ffi_prep_closure_loc instead"))) 325 #elif defined(__GNUC__) && __GNUC__ >= 3 326 __attribute__((deprecated)) 327 #endif 328 ; 329 330 FFI_EXTERN ffi_status 331 ffi_prep_closure_loc (ffi_closure*, 332 ffi_cif *, 333 void (*fun)(ffi_cif*,void*,void**,void*), 334 void *user_data, 335 void*codeloc); 336 337 #ifdef __sgi 338 # pragma pack 8 339 #endif 340 typedef struct { 341 #if 0 342 void *trampoline_table; 343 void *trampoline_table_entry; 344 #else 345 char tramp[FFI_TRAMPOLINE_SIZE]; 346 #endif 347 ffi_cif *cif; 348 349 #if !FFI_NATIVE_RAW_API 350 351 /* If this is enabled, then a raw closure has the same layout 352 as a regular closure. We use this to install an intermediate 353 handler to do the transaltion, void** -> ffi_raw*. */ 354 355 void (*translate_args)(ffi_cif*,void*,void**,void*); 356 void *this_closure; 357 358 #endif 359 360 void (*fun)(ffi_cif*,void*,ffi_raw*,void*); 361 void *user_data; 362 363 } ffi_raw_closure; 364 365 typedef struct { 366 #if 0 367 void *trampoline_table; 368 void *trampoline_table_entry; 369 #else 370 char tramp[FFI_TRAMPOLINE_SIZE]; 371 #endif 372 373 ffi_cif *cif; 374 375 #if !FFI_NATIVE_RAW_API 376 377 /* If this is enabled, then a raw closure has the same layout 378 as a regular closure. We use this to install an intermediate 379 handler to do the translation, void** -> ffi_raw*. */ 380 381 void (*translate_args)(ffi_cif*,void*,void**,void*); 382 void *this_closure; 383 384 #endif 385 386 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); 387 void *user_data; 388 389 } ffi_java_raw_closure; 390 391 FFI_EXTERN ffi_status 392 ffi_prep_raw_closure (ffi_raw_closure*, 393 ffi_cif *cif, 394 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 395 void *user_data); 396 397 FFI_EXTERN ffi_status 398 ffi_prep_raw_closure_loc (ffi_raw_closure*, 399 ffi_cif *cif, 400 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 401 void *user_data, 402 void *codeloc); 403 404 FFI_EXTERN ffi_status 405 ffi_prep_java_raw_closure (ffi_java_raw_closure*, 406 ffi_cif *cif, 407 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), 408 void *user_data); 409 410 FFI_EXTERN ffi_status 411 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, 412 ffi_cif *cif, 413 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), 414 void *user_data, 415 void *codeloc); 416 417 #endif /* FFI_CLOSURES */ 418 419 #if FFI_GO_CLOSURES 420 421 typedef struct { 422 void *tramp; 423 ffi_cif *cif; 424 void (*fun)(ffi_cif*,void*,void**,void*); 425 } ffi_go_closure; 426 427 FFI_EXTERN 428 ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *, 429 void (*fun)(ffi_cif*,void*,void**,void*)); 430 431 FFI_EXTERN 432 void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, 433 void **avalue, void *closure); 434 435 #endif /* FFI_GO_CLOSURES */ 436 437 /* ---- Public interface definition -------------------------------------- */ 438 439 FFI_EXTERN 440 ffi_status ffi_prep_cif(ffi_cif *cif, 441 ffi_abi abi, 442 unsigned int nargs, 443 ffi_type *rtype, 444 ffi_type **atypes); 445 446 FFI_EXTERN 447 ffi_status ffi_prep_cif_var(ffi_cif *cif, 448 ffi_abi abi, 449 unsigned int nfixedargs, 450 unsigned int ntotalargs, 451 ffi_type *rtype, 452 ffi_type **atypes); 453 454 FFI_EXTERN 455 void ffi_call(ffi_cif *cif, 456 void (*fn)(void), 457 void *rvalue, 458 void **avalue); 459 460 FFI_EXTERN 461 ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, 462 size_t *offsets); 463 464 /* Useful for eliminating compiler warnings. */ 465 #define FFI_FN(f) ((void (*)(void))f) 466 467 /* ---- Definitions shared with assembly code ---------------------------- */ 468 469 #endif /* !LIBFFI_ASM */ 470 471 /* If these change, update src/mips/ffitarget.h. */ 472 #define FFI_TYPE_VOID 0 473 #define FFI_TYPE_INT 1 474 #define FFI_TYPE_FLOAT 2 475 #define FFI_TYPE_DOUBLE 3 476 #if 0 477 #define FFI_TYPE_LONGDOUBLE 4 478 #else 479 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE 480 #endif 481 #define FFI_TYPE_UINT8 5 482 #define FFI_TYPE_SINT8 6 483 #define FFI_TYPE_UINT16 7 484 #define FFI_TYPE_SINT16 8 485 #define FFI_TYPE_UINT32 9 486 #define FFI_TYPE_SINT32 10 487 #define FFI_TYPE_UINT64 11 488 #define FFI_TYPE_SINT64 12 489 #define FFI_TYPE_STRUCT 13 490 #define FFI_TYPE_POINTER 14 491 #define FFI_TYPE_COMPLEX 15 492 493 /* This should always refer to the last type code (for sanity checks). */ 494 #define FFI_TYPE_LAST FFI_TYPE_COMPLEX 495 496 #ifdef __cplusplus 497 } 498 #endif 499 500 #endif 501