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

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