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