1/* -----------------------------------------------------------------*-C-*- 2 libffi @VERSION@ - Copyright (c) 2011, 2014, 2019 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 48extern "C" { 49#endif 50 51/* Specify which architecture libffi is configured for. */ 52#ifndef @TARGET@ 53#define @TARGET@ 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 103typedef 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. */ 187FFI_EXTERN ffi_type ffi_type_void; 188FFI_EXTERN ffi_type ffi_type_uint8; 189FFI_EXTERN ffi_type ffi_type_sint8; 190FFI_EXTERN ffi_type ffi_type_uint16; 191FFI_EXTERN ffi_type ffi_type_sint16; 192FFI_EXTERN ffi_type ffi_type_uint32; 193FFI_EXTERN ffi_type ffi_type_sint32; 194FFI_EXTERN ffi_type ffi_type_uint64; 195FFI_EXTERN ffi_type ffi_type_sint64; 196FFI_EXTERN ffi_type ffi_type_float; 197FFI_EXTERN ffi_type ffi_type_double; 198FFI_EXTERN ffi_type ffi_type_pointer; 199 200#if @HAVE_LONG_DOUBLE@ 201FFI_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 207FFI_EXTERN ffi_type ffi_type_complex_float; 208FFI_EXTERN ffi_type ffi_type_complex_double; 209#if @HAVE_LONG_DOUBLE@ 210FFI_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 217typedef enum { 218 FFI_OK = 0, 219 FFI_BAD_TYPEDEF, 220 FFI_BAD_ABI 221} ffi_status; 222 223typedef 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 249typedef 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. */ 260typedef 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 268typedef ffi_raw ffi_java_raw; 269#endif 270 271 272FFI_API 273void ffi_raw_call (ffi_cif *cif, 274 void (*fn)(void), 275 void *rvalue, 276 ffi_raw *avalue); 277 278FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); 279FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); 280FFI_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#if !FFI_NATIVE_RAW_API 287FFI_API 288void ffi_java_raw_call (ffi_cif *cif, 289 void (*fn)(void), 290 void *rvalue, 291 ffi_java_raw *avalue) __attribute__((deprecated)); 292#endif 293 294FFI_API 295void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated)); 296FFI_API 297void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated)); 298FFI_API 299size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated)); 300 301/* ---- Definitions for closures ----------------------------------------- */ 302 303#if FFI_CLOSURES 304 305#ifdef _MSC_VER 306__declspec(align(8)) 307#endif 308typedef struct { 309#if @FFI_EXEC_TRAMPOLINE_TABLE@ 310 void *trampoline_table; 311 void *trampoline_table_entry; 312#else 313 char tramp[FFI_TRAMPOLINE_SIZE]; 314#endif 315 ffi_cif *cif; 316 void (*fun)(ffi_cif*,void*,void**,void*); 317 void *user_data; 318} ffi_closure 319#ifdef __GNUC__ 320 __attribute__((aligned (8))) 321#endif 322 ; 323 324#ifndef __GNUC__ 325# ifdef __sgi 326# pragma pack 0 327# endif 328#endif 329 330FFI_API void *ffi_closure_alloc (size_t size, void **code); 331FFI_API void ffi_closure_free (void *); 332 333FFI_API ffi_status 334ffi_prep_closure (ffi_closure*, 335 ffi_cif *, 336 void (*fun)(ffi_cif*,void*,void**,void*), 337 void *user_data) 338#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405) 339 __attribute__((deprecated ("use ffi_prep_closure_loc instead"))) 340#elif defined(__GNUC__) && __GNUC__ >= 3 341 __attribute__((deprecated)) 342#endif 343 ; 344 345FFI_API ffi_status 346ffi_prep_closure_loc (ffi_closure*, 347 ffi_cif *, 348 void (*fun)(ffi_cif*,void*,void**,void*), 349 void *user_data, 350 void*codeloc); 351 352#ifdef __sgi 353# pragma pack 8 354#endif 355typedef struct { 356#if @FFI_EXEC_TRAMPOLINE_TABLE@ 357 void *trampoline_table; 358 void *trampoline_table_entry; 359#else 360 char tramp[FFI_TRAMPOLINE_SIZE]; 361#endif 362 ffi_cif *cif; 363 364#if !FFI_NATIVE_RAW_API 365 366 /* If this is enabled, then a raw closure has the same layout 367 as a regular closure. We use this to install an intermediate 368 handler to do the transaltion, void** -> ffi_raw*. */ 369 370 void (*translate_args)(ffi_cif*,void*,void**,void*); 371 void *this_closure; 372 373#endif 374 375 void (*fun)(ffi_cif*,void*,ffi_raw*,void*); 376 void *user_data; 377 378} ffi_raw_closure; 379 380typedef struct { 381#if @FFI_EXEC_TRAMPOLINE_TABLE@ 382 void *trampoline_table; 383 void *trampoline_table_entry; 384#else 385 char tramp[FFI_TRAMPOLINE_SIZE]; 386#endif 387 388 ffi_cif *cif; 389 390#if !FFI_NATIVE_RAW_API 391 392 /* If this is enabled, then a raw closure has the same layout 393 as a regular closure. We use this to install an intermediate 394 handler to do the translation, void** -> ffi_raw*. */ 395 396 void (*translate_args)(ffi_cif*,void*,void**,void*); 397 void *this_closure; 398 399#endif 400 401 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); 402 void *user_data; 403 404} ffi_java_raw_closure; 405 406FFI_API ffi_status 407ffi_prep_raw_closure (ffi_raw_closure*, 408 ffi_cif *cif, 409 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 410 void *user_data); 411 412FFI_API ffi_status 413ffi_prep_raw_closure_loc (ffi_raw_closure*, 414 ffi_cif *cif, 415 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 416 void *user_data, 417 void *codeloc); 418 419#if !FFI_NATIVE_RAW_API 420FFI_API ffi_status 421ffi_prep_java_raw_closure (ffi_java_raw_closure*, 422 ffi_cif *cif, 423 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), 424 void *user_data) __attribute__((deprecated)); 425 426FFI_API ffi_status 427ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, 428 ffi_cif *cif, 429 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), 430 void *user_data, 431 void *codeloc) __attribute__((deprecated)); 432#endif 433 434#endif /* FFI_CLOSURES */ 435 436#if FFI_GO_CLOSURES 437 438typedef struct { 439 void *tramp; 440 ffi_cif *cif; 441 void (*fun)(ffi_cif*,void*,void**,void*); 442} ffi_go_closure; 443 444FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *, 445 void (*fun)(ffi_cif*,void*,void**,void*)); 446 447FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, 448 void **avalue, void *closure); 449 450#endif /* FFI_GO_CLOSURES */ 451 452/* ---- Public interface definition -------------------------------------- */ 453 454FFI_API 455ffi_status ffi_prep_cif(ffi_cif *cif, 456 ffi_abi abi, 457 unsigned int nargs, 458 ffi_type *rtype, 459 ffi_type **atypes); 460 461FFI_API 462ffi_status ffi_prep_cif_var(ffi_cif *cif, 463 ffi_abi abi, 464 unsigned int nfixedargs, 465 unsigned int ntotalargs, 466 ffi_type *rtype, 467 ffi_type **atypes); 468 469FFI_API 470void ffi_call(ffi_cif *cif, 471 void (*fn)(void), 472 void *rvalue, 473 void **avalue); 474 475FFI_API 476ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, 477 size_t *offsets); 478 479/* Useful for eliminating compiler warnings. */ 480#define FFI_FN(f) ((void (*)(void))f) 481 482/* ---- Definitions shared with assembly code ---------------------------- */ 483 484#endif 485 486/* If these change, update src/mips/ffitarget.h. */ 487#define FFI_TYPE_VOID 0 488#define FFI_TYPE_INT 1 489#define FFI_TYPE_FLOAT 2 490#define FFI_TYPE_DOUBLE 3 491#if @HAVE_LONG_DOUBLE@ 492#define FFI_TYPE_LONGDOUBLE 4 493#else 494#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE 495#endif 496#define FFI_TYPE_UINT8 5 497#define FFI_TYPE_SINT8 6 498#define FFI_TYPE_UINT16 7 499#define FFI_TYPE_SINT16 8 500#define FFI_TYPE_UINT32 9 501#define FFI_TYPE_SINT32 10 502#define FFI_TYPE_UINT64 11 503#define FFI_TYPE_SINT64 12 504#define FFI_TYPE_STRUCT 13 505#define FFI_TYPE_POINTER 14 506#define FFI_TYPE_COMPLEX 15 507 508/* This should always refer to the last type code (for sanity checks). */ 509#define FFI_TYPE_LAST FFI_TYPE_COMPLEX 510 511#ifdef __cplusplus 512} 513#endif 514 515#endif 516