libffi (3.4.4)
1 /* -----------------------------------------------------------------*-C-*-
2 libffi 3.4.4
3 - Copyright (c) 2011, 2014, 2019, 2021, 2022 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
49 extern "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
129 typedef 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
144 # if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
145 # define FFI_API __declspec(dllexport)
146 # elif !defined FFI_BUILDING /* Importing libffi.DLL */
147 # define FFI_API __declspec(dllimport)
148 # else /* Building/linking static library */
149 # define FFI_API
150 # endif
151 #else
152 # define FFI_API
153 #endif
154
155 /* The externally visible type declarations also need the MSVC DLL
156 decorations, or they will not be exported from the object file. */
157 #if defined LIBFFI_HIDE_BASIC_TYPES
158 # define FFI_EXTERN FFI_API
159 #else
160 # define FFI_EXTERN extern FFI_API
161 #endif
162
163 #ifndef LIBFFI_HIDE_BASIC_TYPES
164 #if SCHAR_MAX == 127
165 # define ffi_type_uchar ffi_type_uint8
166 # define ffi_type_schar ffi_type_sint8
167 #else
168 #error "char size not supported"
169 #endif
170
171 #if SHRT_MAX == 32767
172 # define ffi_type_ushort ffi_type_uint16
173 # define ffi_type_sshort ffi_type_sint16
174 #elif SHRT_MAX == 2147483647
175 # define ffi_type_ushort ffi_type_uint32
176 # define ffi_type_sshort ffi_type_sint32
177 #else
178 #error "short size not supported"
179 #endif
180
181 #if INT_MAX == 32767
182 # define ffi_type_uint ffi_type_uint16
183 # define ffi_type_sint ffi_type_sint16
184 #elif INT_MAX == 2147483647
185 # define ffi_type_uint ffi_type_uint32
186 # define ffi_type_sint ffi_type_sint32
187 #elif INT_MAX == 9223372036854775807
188 # define ffi_type_uint ffi_type_uint64
189 # define ffi_type_sint ffi_type_sint64
190 #else
191 #error "int size not supported"
192 #endif
193
194 #if LONG_MAX == 2147483647
195 # if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
196 #error "no 64-bit data type supported"
197 # endif
198 #elif LONG_MAX != FFI_64_BIT_MAX
199 #error "long size not supported"
200 #endif
201
202 #if LONG_MAX == 2147483647
203 # define ffi_type_ulong ffi_type_uint32
204 # define ffi_type_slong ffi_type_sint32
205 #elif LONG_MAX == FFI_64_BIT_MAX
206 # define ffi_type_ulong ffi_type_uint64
207 # define ffi_type_slong ffi_type_sint64
208 #else
209 #error "long size not supported"
210 #endif
211
212 /* These are defined in types.c. */
213 FFI_EXTERN ffi_type ffi_type_void;
214 FFI_EXTERN ffi_type ffi_type_uint8;
215 FFI_EXTERN ffi_type ffi_type_sint8;
216 FFI_EXTERN ffi_type ffi_type_uint16;
217 FFI_EXTERN ffi_type ffi_type_sint16;
218 FFI_EXTERN ffi_type ffi_type_uint32;
219 FFI_EXTERN ffi_type ffi_type_sint32;
220 FFI_EXTERN ffi_type ffi_type_uint64;
221 FFI_EXTERN ffi_type ffi_type_sint64;
222 FFI_EXTERN ffi_type ffi_type_float;
223 FFI_EXTERN ffi_type ffi_type_double;
224 FFI_EXTERN ffi_type ffi_type_pointer;
225
226 #if 1
227 FFI_EXTERN ffi_type ffi_type_longdouble;
228 #else
229 #define ffi_type_longdouble ffi_type_double
230 #endif
231
232 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
233 FFI_EXTERN ffi_type ffi_type_complex_float;
234 FFI_EXTERN ffi_type ffi_type_complex_double;
235 #if 1
236 FFI_EXTERN ffi_type ffi_type_complex_longdouble;
237 #else
238 #define ffi_type_complex_longdouble ffi_type_complex_double
239 #endif
240 #endif
241 #endif /* LIBFFI_HIDE_BASIC_TYPES */
242
243 typedef enum {
244 FFI_OK = 0,
245 FFI_BAD_TYPEDEF,
246 FFI_BAD_ABI,
247 FFI_BAD_ARGTYPE
248 } ffi_status;
249
250 typedef struct {
251 ffi_abi abi;
252 unsigned nargs;
253 ffi_type **arg_types;
254 ffi_type *rtype;
255 unsigned bytes;
256 unsigned flags;
257 #ifdef FFI_EXTRA_CIF_FIELDS
258 FFI_EXTRA_CIF_FIELDS;
259 #endif
260 } ffi_cif;
261
262 /* ---- Definitions for the raw API -------------------------------------- */
263
264 #ifndef FFI_SIZEOF_ARG
265 # if LONG_MAX == 2147483647
266 # define FFI_SIZEOF_ARG 4
267 # elif LONG_MAX == FFI_64_BIT_MAX
268 # define FFI_SIZEOF_ARG 8
269 # endif
270 #endif
271
272 #ifndef FFI_SIZEOF_JAVA_RAW
273 # define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
274 #endif
275
276 typedef union {
277 ffi_sarg sint;
278 ffi_arg uint;
279 float flt;
280 char data[FFI_SIZEOF_ARG];
281 void* ptr;
282 } ffi_raw;
283
284 #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
285 /* This is a special case for mips64/n32 ABI (and perhaps others) where
286 sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
287 typedef union {
288 signed int sint;
289 unsigned int uint;
290 float flt;
291 char data[FFI_SIZEOF_JAVA_RAW];
292 void* ptr;
293 } ffi_java_raw;
294 #else
295 typedef ffi_raw ffi_java_raw;
296 #endif
297
298
299 FFI_API
300 void ffi_raw_call (ffi_cif *cif,
301 void (*fn)(void),
302 void *rvalue,
303 ffi_raw *avalue);
304
305 FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
306 FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
307 FFI_API size_t ffi_raw_size (ffi_cif *cif);
308
309 /* This is analogous to the raw API, except it uses Java parameter
310 packing, even on 64-bit machines. I.e. on 64-bit machines longs
311 and doubles are followed by an empty 64-bit word. */
312
313 #if !FFI_NATIVE_RAW_API
314 FFI_API
315 void ffi_java_raw_call (ffi_cif *cif,
316 void (*fn)(void),
317 void *rvalue,
318 ffi_java_raw *avalue) __attribute__((deprecated));
319 #endif
320
321 FFI_API
322 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
323 FFI_API
324 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
325 FFI_API
326 size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
327
328 /* ---- Definitions for closures ----------------------------------------- */
329
330 #if FFI_CLOSURES
331
332 #ifdef _MSC_VER
333 __declspec(align(8))
334 #endif
335 typedef struct {
336 #if 0
337 void *trampoline_table;
338 void *trampoline_table_entry;
339 #else
340 union {
341 char tramp[FFI_TRAMPOLINE_SIZE];
342 void *ftramp;
343 };
344 #endif
345 ffi_cif *cif;
346 void (*fun)(ffi_cif*,void*,void**,void*);
347 void *user_data;
348 #if defined(_MSC_VER) && defined(_M_IX86)
349 void *padding;
350 #endif
351 } ffi_closure
352 #ifdef __GNUC__
353 __attribute__((aligned (8)))
354 #endif
355 ;
356
357 #ifndef __GNUC__
358 # ifdef __sgi
359 # pragma pack 0
360 # endif
361 #endif
362
363 FFI_API void *ffi_closure_alloc (size_t size, void **code);
364 FFI_API void ffi_closure_free (void *);
365
366 #if defined(PA_LINUX) || defined(PA_HPUX)
367 #define FFI_CLOSURE_PTR(X) ((void *)((unsigned int)(X) | 2))
368 #define FFI_RESTORE_PTR(X) ((void *)((unsigned int)(X) & ~3))
369 #else
370 #define FFI_CLOSURE_PTR(X) (X)
371 #define FFI_RESTORE_PTR(X) (X)
372 #endif
373
374 FFI_API ffi_status
375 ffi_prep_closure (ffi_closure*,
376 ffi_cif *,
377 void (*fun)(ffi_cif*,void*,void**,void*),
378 void *user_data)
379 #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
380 __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
381 #elif defined(__GNUC__) && __GNUC__ >= 3
382 __attribute__((deprecated))
383 #endif
384 ;
385
386 FFI_API ffi_status
387 ffi_prep_closure_loc (ffi_closure*,
388 ffi_cif *,
389 void (*fun)(ffi_cif*,void*,void**,void*),
390 void *user_data,
391 void *codeloc);
392
393 #ifdef __sgi
394 # pragma pack 8
395 #endif
396 typedef struct {
397 #if 0
398 void *trampoline_table;
399 void *trampoline_table_entry;
400 #else
401 char tramp[FFI_TRAMPOLINE_SIZE];
402 #endif
403 ffi_cif *cif;
404
405 #if !FFI_NATIVE_RAW_API
406
407 /* If this is enabled, then a raw closure has the same layout
408 as a regular closure. We use this to install an intermediate
409 handler to do the translation, void** -> ffi_raw*. */
410
411 void (*translate_args)(ffi_cif*,void*,void**,void*);
412 void *this_closure;
413
414 #endif
415
416 void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
417 void *user_data;
418
419 } ffi_raw_closure;
420
421 typedef struct {
422 #if 0
423 void *trampoline_table;
424 void *trampoline_table_entry;
425 #else
426 char tramp[FFI_TRAMPOLINE_SIZE];
427 #endif
428
429 ffi_cif *cif;
430
431 #if !FFI_NATIVE_RAW_API
432
433 /* If this is enabled, then a raw closure has the same layout
434 as a regular closure. We use this to install an intermediate
435 handler to do the translation, void** -> ffi_raw*. */
436
437 void (*translate_args)(ffi_cif*,void*,void**,void*);
438 void *this_closure;
439
440 #endif
441
442 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
443 void *user_data;
444
445 } ffi_java_raw_closure;
446
447 FFI_API ffi_status
448 ffi_prep_raw_closure (ffi_raw_closure*,
449 ffi_cif *cif,
450 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
451 void *user_data);
452
453 FFI_API ffi_status
454 ffi_prep_raw_closure_loc (ffi_raw_closure*,
455 ffi_cif *cif,
456 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
457 void *user_data,
458 void *codeloc);
459
460 #if !FFI_NATIVE_RAW_API
461 FFI_API ffi_status
462 ffi_prep_java_raw_closure (ffi_java_raw_closure*,
463 ffi_cif *cif,
464 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
465 void *user_data) __attribute__((deprecated));
466
467 FFI_API ffi_status
468 ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
469 ffi_cif *cif,
470 void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
471 void *user_data,
472 void *codeloc) __attribute__((deprecated));
473 #endif
474
475 #endif /* FFI_CLOSURES */
476
477 #if FFI_GO_CLOSURES
478
479 typedef struct {
480 void *tramp;
481 ffi_cif *cif;
482 void (*fun)(ffi_cif*,void*,void**,void*);
483 } ffi_go_closure;
484
485 FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
486 void (*fun)(ffi_cif*,void*,void**,void*));
487
488 FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
489 void **avalue, void *closure);
490
491 #endif /* FFI_GO_CLOSURES */
492
493 /* ---- Public interface definition -------------------------------------- */
494
495 FFI_API
496 ffi_status ffi_prep_cif(ffi_cif *cif,
497 ffi_abi abi,
498 unsigned int nargs,
499 ffi_type *rtype,
500 ffi_type **atypes);
501
502 FFI_API
503 ffi_status ffi_prep_cif_var(ffi_cif *cif,
504 ffi_abi abi,
505 unsigned int nfixedargs,
506 unsigned int ntotalargs,
507 ffi_type *rtype,
508 ffi_type **atypes);
509
510 FFI_API
511 void ffi_call(ffi_cif *cif,
512 void (*fn)(void),
513 void *rvalue,
514 void **avalue);
515
516 FFI_API
517 ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
518 size_t *offsets);
519
520 /* Useful for eliminating compiler warnings. */
521 #define FFI_FN(f) ((void (*)(void))f)
522
523 /* ---- Definitions shared with assembly code ---------------------------- */
524
525 #endif
526
527 #ifdef __cplusplus
528 }
529 #endif
530
531 #endif