• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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