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

source code of include/x86_64-linux-gnu/ffi.h