···11+libffi - Copyright (c) 1996-2003 Red Hat, Inc.
22+33+Permission is hereby granted, free of charge, to any person obtaining
44+a copy of this software and associated documentation files (the
55+``Software''), to deal in the Software without restriction, including
66+without limitation the rights to use, copy, modify, merge, publish,
77+distribute, sublicense, and/or sell copies of the Software, and to
88+permit persons to whom the Software is furnished to do so, subject to
99+the following conditions:
1010+1111+The above copyright notice and this permission notice shall be included
1212+in all copies or substantial portions of the Software.
1313+1414+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1515+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1616+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1717+IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1818+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1919+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2020+OTHER DEALINGS IN THE SOFTWARE.
+500
src/libffi/README
···11+This directory contains the libffi package, which is not part of GCC but
22+shipped with GCC as convenience.
33+44+Status
55+======
66+77+libffi-2.00 has not been released yet! This is a development snapshot!
88+99+libffi-1.20 was released on October 5, 1998. Check the libffi web
1010+page for updates: <URL:http://sources.redhat.com/libffi/>.
1111+1212+1313+What is libffi?
1414+===============
1515+1616+Compilers for high level languages generate code that follow certain
1717+conventions. These conventions are necessary, in part, for separate
1818+compilation to work. One such convention is the "calling
1919+convention". The "calling convention" is essentially a set of
2020+assumptions made by the compiler about where function arguments will
2121+be found on entry to a function. A "calling convention" also specifies
2222+where the return value for a function is found.
2323+2424+Some programs may not know at the time of compilation what arguments
2525+are to be passed to a function. For instance, an interpreter may be
2626+told at run-time about the number and types of arguments used to call
2727+a given function. Libffi can be used in such programs to provide a
2828+bridge from the interpreter program to compiled code.
2929+3030+The libffi library provides a portable, high level programming
3131+interface to various calling conventions. This allows a programmer to
3232+call any function specified by a call interface description at run
3333+time.
3434+3535+Ffi stands for Foreign Function Interface. A foreign function
3636+interface is the popular name for the interface that allows code
3737+written in one language to call code written in another language. The
3838+libffi library really only provides the lowest, machine dependent
3939+layer of a fully featured foreign function interface. A layer must
4040+exist above libffi that handles type conversions for values passed
4141+between the two languages.
4242+4343+4444+Supported Platforms and Prerequisites
4545+=====================================
4646+4747+Libffi has been ported to:
4848+4949+ SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
5050+5151+ Irix 5.3 & 6.2 (System V/o32 & n32)
5252+5353+ Intel x86 - Linux (System V ABI)
5454+5555+ Alpha - Linux and OSF/1
5656+5757+ m68k - Linux (System V ABI)
5858+5959+ PowerPC - Linux (System V ABI, Darwin, AIX)
6060+6161+ ARM - Linux (System V ABI)
6262+6363+Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
6464+that other versions will work. Libffi has also been built and tested
6565+with the SGI compiler tools.
6666+6767+On PowerPC, the tests failed (see the note below).
6868+6969+You must use GNU make to build libffi. SGI's make will not work.
7070+Sun's probably won't either.
7171+7272+If you port libffi to another platform, please let me know! I assume
7373+that some will be easy (x86 NetBSD), and others will be more difficult
7474+(HP).
7575+7676+7777+Installing libffi
7878+=================
7979+8080+[Note: before actually performing any of these installation steps,
8181+ you may wish to read the "Platform Specific Notes" below.]
8282+8383+First you must configure the distribution for your particular
8484+system. Go to the directory you wish to build libffi in and run the
8585+"configure" program found in the root directory of the libffi source
8686+distribution.
8787+8888+You may want to tell configure where to install the libffi library and
8989+header files. To do that, use the --prefix configure switch. Libffi
9090+will install under /usr/local by default.
9191+9292+If you want to enable extra run-time debugging checks use the the
9393+--enable-debug configure switch. This is useful when your program dies
9494+mysteriously while using libffi.
9595+9696+Another useful configure switch is --enable-purify-safety. Using this
9797+will add some extra code which will suppress certain warnings when you
9898+are using Purify with libffi. Only use this switch when using
9999+Purify, as it will slow down the library.
100100+101101+Configure has many other options. Use "configure --help" to see them all.
102102+103103+Once configure has finished, type "make". Note that you must be using
104104+GNU make. SGI's make will not work. Sun's probably won't either.
105105+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
106106+107107+To ensure that libffi is working as advertised, type "make test".
108108+109109+To install the library and header files, type "make install".
110110+111111+112112+Using libffi
113113+============
114114+115115+ The Basics
116116+ ----------
117117+118118+Libffi assumes that you have a pointer to the function you wish to
119119+call and that you know the number and types of arguments to pass it,
120120+as well as the return type of the function.
121121+122122+The first thing you must do is create an ffi_cif object that matches
123123+the signature of the function you wish to call. The cif in ffi_cif
124124+stands for Call InterFace. To prepare a call interface object, use the
125125+following function:
126126+127127+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
128128+ unsigned int nargs,
129129+ ffi_type *rtype, ffi_type **atypes);
130130+131131+ CIF is a pointer to the call interface object you wish
132132+ to initialize.
133133+134134+ ABI is an enum that specifies the calling convention
135135+ to use for the call. FFI_DEFAULT_ABI defaults
136136+ to the system's native calling convention. Other
137137+ ABI's may be used with care. They are system
138138+ specific.
139139+140140+ NARGS is the number of arguments this function accepts.
141141+ libffi does not yet support vararg functions.
142142+143143+ RTYPE is a pointer to an ffi_type structure that represents
144144+ the return type of the function. Ffi_type objects
145145+ describe the types of values. libffi provides
146146+ ffi_type objects for many of the native C types:
147147+ signed int, unsigned int, signed char, unsigned char,
148148+ etc. There is also a pointer ffi_type object and
149149+ a void ffi_type. Use &ffi_type_void for functions that
150150+ don't return values.
151151+152152+ ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
153153+ If NARGS is 0, this is ignored.
154154+155155+156156+ffi_prep_cif will return a status code that you are responsible
157157+for checking. It will be one of the following:
158158+159159+ FFI_OK - All is good.
160160+161161+ FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
162162+ came across is bad.
163163+164164+165165+Before making the call, the VALUES vector should be initialized
166166+with pointers to the appropriate argument values.
167167+168168+To call the the function using the initialized ffi_cif, use the
169169+ffi_call function:
170170+171171+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
172172+173173+ CIF is a pointer to the ffi_cif initialized specifically
174174+ for this function.
175175+176176+ FN is a pointer to the function you want to call.
177177+178178+ RVALUE is a pointer to a chunk of memory that is to hold the
179179+ result of the function call. Currently, it must be
180180+ at least one word in size (except for the n32 version
181181+ under Irix 6.x, which must be a pointer to an 8 byte
182182+ aligned value (a long long). It must also be at least
183183+ word aligned (depending on the return type, and the
184184+ system's alignment requirements). If RTYPE is
185185+ &ffi_type_void, this is ignored. If RVALUE is NULL,
186186+ the return value is discarded.
187187+188188+ AVALUES is a vector of void* that point to the memory locations
189189+ holding the argument values for a call.
190190+ If NARGS is 0, this is ignored.
191191+192192+193193+If you are expecting a return value from FN it will have been stored
194194+at RVALUE.
195195+196196+197197+198198+ An Example
199199+ ----------
200200+201201+Here is a trivial example that calls puts() a few times.
202202+203203+ #include <stdio.h>
204204+ #include <ffi.h>
205205+206206+ int main()
207207+ {
208208+ ffi_cif cif;
209209+ ffi_type *args[1];
210210+ void *values[1];
211211+ char *s;
212212+ int rc;
213213+214214+ /* Initialize the argument info vectors */
215215+ args[0] = &ffi_type_uint;
216216+ values[0] = &s;
217217+218218+ /* Initialize the cif */
219219+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
220220+ &ffi_type_uint, args) == FFI_OK)
221221+ {
222222+ s = "Hello World!";
223223+ ffi_call(&cif, puts, &rc, values);
224224+ /* rc now holds the result of the call to puts */
225225+226226+ /* values holds a pointer to the function's arg, so to
227227+ call puts() again all we need to do is change the
228228+ value of s */
229229+ s = "This is cool!";
230230+ ffi_call(&cif, puts, &rc, values);
231231+ }
232232+233233+ return 0;
234234+ }
235235+236236+237237+238238+ Aggregate Types
239239+ ---------------
240240+241241+Although libffi has no special support for unions or bit-fields, it is
242242+perfectly happy passing structures back and forth. You must first
243243+describe the structure to libffi by creating a new ffi_type object
244244+for it. Here is the definition of ffi_type:
245245+246246+ typedef struct _ffi_type
247247+ {
248248+ unsigned size;
249249+ short alignment;
250250+ short type;
251251+ struct _ffi_type **elements;
252252+ } ffi_type;
253253+254254+All structures must have type set to FFI_TYPE_STRUCT. You may set
255255+size and alignment to 0. These will be calculated and reset to the
256256+appropriate values by ffi_prep_cif().
257257+258258+elements is a NULL terminated array of pointers to ffi_type objects
259259+that describe the type of the structure elements. These may, in turn,
260260+be structure elements.
261261+262262+The following example initializes a ffi_type object representing the
263263+tm struct from Linux's time.h:
264264+265265+ struct tm {
266266+ int tm_sec;
267267+ int tm_min;
268268+ int tm_hour;
269269+ int tm_mday;
270270+ int tm_mon;
271271+ int tm_year;
272272+ int tm_wday;
273273+ int tm_yday;
274274+ int tm_isdst;
275275+ /* Those are for future use. */
276276+ long int __tm_gmtoff__;
277277+ __const char *__tm_zone__;
278278+ };
279279+280280+ {
281281+ ffi_type tm_type;
282282+ ffi_type *tm_type_elements[12];
283283+ int i;
284284+285285+ tm_type.size = tm_type.alignment = 0;
286286+ tm_type.elements = &tm_type_elements;
287287+288288+ for (i = 0; i < 9; i++)
289289+ tm_type_elements[i] = &ffi_type_sint;
290290+291291+ tm_type_elements[9] = &ffi_type_slong;
292292+ tm_type_elements[10] = &ffi_type_pointer;
293293+ tm_type_elements[11] = NULL;
294294+295295+ /* tm_type can now be used to represent tm argument types and
296296+ return types for ffi_prep_cif() */
297297+ }
298298+299299+300300+301301+Platform Specific Notes
302302+=======================
303303+304304+ Intel x86
305305+ ---------
306306+307307+There are no known problems with the x86 port.
308308+309309+ Sun SPARC - SunOS 4.1.3 & Solaris 2.x
310310+ -------------------------------------
311311+312312+You must use GNU Make to build libffi on Sun platforms.
313313+314314+ MIPS - Irix 5.3 & 6.x
315315+ ---------------------
316316+317317+Irix 6.2 and better supports three different calling conventions: o32,
318318+n32 and n64. Currently, libffi only supports both o32 and n32 under
319319+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
320320+configured for whichever calling convention it was built for.
321321+322322+By default, the configure script will try to build libffi with the GNU
323323+development tools. To build libffi with the SGI development tools, set
324324+the environment variable CC to either "cc -32" or "cc -n32" before
325325+running configure under Irix 6.x (depending on whether you want an o32
326326+or n32 library), or just "cc" for Irix 5.3.
327327+328328+With the n32 calling convention, when returning structures smaller
329329+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
330330+Here's one way of forcing this:
331331+332332+ double struct_storage[2];
333333+ my_small_struct *s = (my_small_struct *) struct_storage;
334334+ /* Use s for RVALUE */
335335+336336+If you don't do this you are liable to get spurious bus errors.
337337+338338+"long long" values are not supported yet.
339339+340340+You must use GNU Make to build libffi on SGI platforms.
341341+342342+ ARM - System V ABI
343343+ ------------------
344344+345345+The ARM port was performed on a NetWinder running ARM Linux ELF
346346+(2.0.31) and gcc 2.8.1.
347347+348348+349349+350350+ PowerPC System V ABI
351351+ --------------------
352352+353353+There are two `System V ABI's which libffi implements for PowerPC.
354354+They differ only in how small structures are returned from functions.
355355+356356+In the FFI_SYSV version, structures that are 8 bytes or smaller are
357357+returned in registers. This is what GCC does when it is configured
358358+for solaris, and is what the System V ABI I have (dated September
359359+1995) says.
360360+361361+In the FFI_GCC_SYSV version, all structures are returned the same way:
362362+by passing a pointer as the first argument to the function. This is
363363+what GCC does when it is configured for linux or a generic sysv
364364+target.
365365+366366+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
367367+inconsistency with the SysV ABI: When a procedure is called with many
368368+floating-point arguments, some of them get put on the stack. They are
369369+all supposed to be stored in double-precision format, even if they are
370370+only single-precision, but EGCS stores single-precision arguments as
371371+single-precision anyway. This causes one test to fail (the `many
372372+arguments' test).
373373+374374+375375+What's With The Crazy Comments?
376376+===============================
377377+378378+You might notice a number of cryptic comments in the code, delimited
379379+by /*@ and @*/. These are annotations read by the program LCLint, a
380380+tool for statically checking C programs. You can read all about it at
381381+<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
382382+383383+384384+History
385385+=======
386386+387387+1.20 Oct-5-98
388388+ Raffaele Sena produces ARM port.
389389+390390+1.19 Oct-5-98
391391+ Fixed x86 long double and long long return support.
392392+ m68k bug fixes from Andreas Schwab.
393393+ Patch for DU assembler compatibility for the Alpha from Richard
394394+ Henderson.
395395+396396+1.18 Apr-17-98
397397+ Bug fixes and MIPS configuration changes.
398398+399399+1.17 Feb-24-98
400400+ Bug fixes and m68k port from Andreas Schwab. PowerPC port from
401401+ Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
402402+403403+1.16 Feb-11-98
404404+ Richard Henderson produces Alpha port.
405405+406406+1.15 Dec-4-97
407407+ Fixed an n32 ABI bug. New libtool, auto* support.
408408+409409+1.14 May-13-97
410410+ libtool is now used to generate shared and static libraries.
411411+ Fixed a minor portability problem reported by Russ McManus
412412+ <mcmanr@eq.gs.com>.
413413+414414+1.13 Dec-2-96
415415+ Added --enable-purify-safety to keep Purify from complaining
416416+ about certain low level code.
417417+ Sparc fix for calling functions with < 6 args.
418418+ Linux x86 a.out fix.
419419+420420+1.12 Nov-22-96
421421+ Added missing ffi_type_void, needed for supporting void return
422422+ types. Fixed test case for non MIPS machines. Cygnus Support
423423+ is now Cygnus Solutions.
424424+425425+1.11 Oct-30-96
426426+ Added notes about GNU make.
427427+428428+1.10 Oct-29-96
429429+ Added configuration fix for non GNU compilers.
430430+431431+1.09 Oct-29-96
432432+ Added --enable-debug configure switch. Clean-ups based on LCLint
433433+ feedback. ffi_mips.h is always installed. Many configuration
434434+ fixes. Fixed ffitest.c for sparc builds.
435435+436436+1.08 Oct-15-96
437437+ Fixed n32 problem. Many clean-ups.
438438+439439+1.07 Oct-14-96
440440+ Gordon Irlam rewrites v8.S again. Bug fixes.
441441+442442+1.06 Oct-14-96
443443+ Gordon Irlam improved the sparc port.
444444+445445+1.05 Oct-14-96
446446+ Interface changes based on feedback.
447447+448448+1.04 Oct-11-96
449449+ Sparc port complete (modulo struct passing bug).
450450+451451+1.03 Oct-10-96
452452+ Passing struct args, and returning struct values works for
453453+ all architectures/calling conventions. Expanded tests.
454454+455455+1.02 Oct-9-96
456456+ Added SGI n32 support. Fixed bugs in both o32 and Linux support.
457457+ Added "make test".
458458+459459+1.01 Oct-8-96
460460+ Fixed float passing bug in mips version. Restructured some
461461+ of the code. Builds cleanly with SGI tools.
462462+463463+1.00 Oct-7-96
464464+ First release. No public announcement.
465465+466466+467467+Authors & Credits
468468+=================
469469+470470+libffi was written by Anthony Green <green@cygnus.com>.
471471+472472+Portions of libffi were derived from Gianni Mariani's free gencall
473473+library for Silicon Graphics machines.
474474+475475+The closure mechanism was designed and implemented by Kresten Krab
476476+Thorup.
477477+478478+The Sparc port was derived from code contributed by the fine folks at
479479+Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
480480+made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
481481+482482+The Alpha port was written by Richard Henderson at Cygnus Solutions.
483483+484484+Andreas Schwab ported libffi to m68k Linux and provided a number of
485485+bug fixes.
486486+487487+Geoffrey Keating ported libffi to the PowerPC.
488488+489489+Raffaele Sena ported libffi to the ARM.
490490+491491+Jesper Skov and Andrew Haley both did more than their fair share of
492492+stepping through the code and tracking down bugs.
493493+494494+Thanks also to Tom Tromey for bug fixes and configuration help.
495495+496496+Thanks to Jim Blandy, who provided some useful feedback on the libffi
497497+interface.
498498+499499+If you have a problem, or have found a bug, please send a note to
500500+green@cygnus.com.
+13
src/libffi/README.MacOSX
···11+This is the Xcode/Mac OS X version of libffi.
22+33+It has an Xcode project that builds libffi as a statically linkable library.
44+55+The unit tests assume said library has been built and installed. For now, there is no "in place" unit tests.
66+77+To run the unit tests, invoke:
88+99+ python ./tests/run-tests.py
1010+1111+You must be within the libffi directory when you do this. The whole thing is horribly sensitive to path related issues. At some point, the unit tests will be re-worked to be properly invoked from Xcode.
1212+1313+Note that this is the libffi source with files renamed to be Xcode build friendly. As well, all non-MacOSX related build stuff is stripped.
+226
src/libffi/ffi.c
···11+/* -----------------------------------------------------------------------
22+ prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc.
33+44+ Permission is hereby granted, free of charge, to any person obtaining
55+ a copy of this software and associated documentation files (the
66+ ``Software''), to deal in the Software without restriction, including
77+ without limitation the rights to use, copy, modify, merge, publish,
88+ distribute, sublicense, and/or sell copies of the Software, and to
99+ permit persons to whom the Software is furnished to do so, subject to
1010+ the following conditions:
1111+1212+ The above copyright notice and this permission notice shall be included
1313+ in all copies or substantial portions of the Software.
1414+1515+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1616+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1717+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1818+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1919+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2020+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2121+ OTHER DEALINGS IN THE SOFTWARE.
2222+ ----------------------------------------------------------------------- */
2323+2424+#include <ffi.h>
2525+#include <ffi_common.h>
2626+2727+#include <stdbool.h>
2828+#include <stdlib.h>
2929+3030+/* Round up to FFI_SIZEOF_ARG. */
3131+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
3232+3333+/* Perform machine independent initialization of aggregate type
3434+ specifications. */
3535+3636+static ffi_status
3737+initialize_aggregate(
3838+/*@out@*/ ffi_type* arg)
3939+{
4040+/*@-usedef@*/
4141+4242+ if (arg == NULL || arg->elements == NULL ||
4343+ arg->size != 0 || arg->alignment != 0)
4444+ return FFI_BAD_TYPEDEF;
4545+4646+ ffi_type** ptr = &(arg->elements[0]);
4747+4848+ while ((*ptr) != NULL)
4949+ {
5050+ if (((*ptr)->size == 0) && (initialize_aggregate(*ptr) != FFI_OK))
5151+ return FFI_BAD_TYPEDEF;
5252+5353+ /* Perform a sanity check on the argument type */
5454+ FFI_ASSERT_VALID_TYPE(*ptr);
5555+5656+#ifdef POWERPC_DARWIN
5757+ int curalign = (*ptr)->alignment;
5858+5959+ if (ptr != &(arg->elements[0]))
6060+ {
6161+ if (curalign > 4 && curalign != 16)
6262+ curalign = 4;
6363+ }
6464+6565+ arg->size = ALIGN(arg->size, curalign);
6666+ arg->size += (*ptr)->size;
6767+ arg->alignment = (arg->alignment > curalign) ?
6868+ arg->alignment : curalign;
6969+#else
7070+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
7171+ arg->size += (*ptr)->size;
7272+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
7373+ arg->alignment : (*ptr)->alignment;
7474+#endif
7575+7676+ ptr++;
7777+ }
7878+7979+ /* Structure size includes tail padding. This is important for
8080+ structures that fit in one register on ABIs like the PowerPC64
8181+ Linux ABI that right justify small structs in a register.
8282+ It's also needed for nested structure layout, for example
8383+ struct A { long a; char b; }; struct B { struct A x; char y; };
8484+ should find y at an offset of 2*sizeof(long) and result in a
8585+ total size of 3*sizeof(long). */
8686+ arg->size = ALIGN(arg->size, arg->alignment);
8787+8888+ if (arg->size == 0)
8989+ return FFI_BAD_TYPEDEF;
9090+9191+ return FFI_OK;
9292+9393+/*@=usedef@*/
9494+}
9595+9696+#ifndef __CRIS__
9797+/* The CRIS ABI specifies structure elements to have byte
9898+ alignment only, so it completely overrides this functions,
9999+ which assumes "natural" alignment and padding. */
100100+101101+/* Perform machine independent ffi_cif preparation, then call
102102+ machine dependent routine. */
103103+104104+#if defined(X86_DARWIN)
105105+106106+static inline bool
107107+struct_on_stack(
108108+ int size)
109109+{
110110+ if (size > 8)
111111+ return true;
112112+113113+ /* This is not what the ABI says, but is what is really implemented */
114114+ switch (size)
115115+ {
116116+ case 1:
117117+ case 2:
118118+ case 4:
119119+ case 8:
120120+ return false;
121121+122122+ default:
123123+ return true;
124124+ }
125125+}
126126+127127+#endif // defined(X86_DARWIN)
128128+129129+// Arguments' ffi_type->alignment must be nonzero.
130130+ffi_status
131131+ffi_prep_cif(
132132+/*@out@*/ /*@partial@*/ ffi_cif* cif,
133133+ ffi_abi abi,
134134+ unsigned int nargs,
135135+/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype,
136136+/*@dependent@*/ ffi_type** atypes)
137137+{
138138+ if (cif == NULL)
139139+ return FFI_BAD_TYPEDEF;
140140+141141+ if (abi <= FFI_FIRST_ABI || abi > FFI_DEFAULT_ABI)
142142+ return FFI_BAD_ABI;
143143+144144+ unsigned int bytes = 0;
145145+ unsigned int i;
146146+ ffi_type** ptr;
147147+148148+ cif->abi = abi;
149149+ cif->arg_types = atypes;
150150+ cif->nargs = nargs;
151151+ cif->rtype = rtype;
152152+ cif->flags = 0;
153153+154154+ /* Initialize the return type if necessary */
155155+ /*@-usedef@*/
156156+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
157157+ return FFI_BAD_TYPEDEF;
158158+ /*@=usedef@*/
159159+160160+ /* Perform a sanity check on the return type */
161161+ FFI_ASSERT_VALID_TYPE(cif->rtype);
162162+163163+ /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
164164+#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
165165+ /* Make space for the return structure pointer */
166166+ if (cif->rtype->type == FFI_TYPE_STRUCT
167167+#ifdef SPARC
168168+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
169169+#endif
170170+#ifdef X86_DARWIN
171171+ && (struct_on_stack(cif->rtype->size))
172172+#endif
173173+ )
174174+ bytes = STACK_ARG_SIZE(sizeof(void*));
175175+#endif
176176+177177+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
178178+ {
179179+ /* Initialize any uninitialized aggregate type definitions */
180180+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
181181+ return FFI_BAD_TYPEDEF;
182182+183183+ if ((*ptr)->alignment == 0)
184184+ return FFI_BAD_TYPEDEF;
185185+186186+ /* Perform a sanity check on the argument type, do this
187187+ check after the initialization. */
188188+ FFI_ASSERT_VALID_TYPE(*ptr);
189189+190190+#if defined(X86_DARWIN)
191191+ {
192192+ int align = (*ptr)->alignment;
193193+194194+ if (align > 4)
195195+ align = 4;
196196+197197+ if ((align - 1) & bytes)
198198+ bytes = ALIGN(bytes, align);
199199+200200+ bytes += STACK_ARG_SIZE((*ptr)->size);
201201+ }
202202+#elif !defined __x86_64__ && !defined S390 && !defined PA
203203+#ifdef SPARC
204204+ if (((*ptr)->type == FFI_TYPE_STRUCT
205205+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
206206+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
207207+ && cif->abi != FFI_V9))
208208+ bytes += sizeof(void*);
209209+ else
210210+#endif
211211+ {
212212+ /* Add any padding if necessary */
213213+ if (((*ptr)->alignment - 1) & bytes)
214214+ bytes = ALIGN(bytes, (*ptr)->alignment);
215215+216216+ bytes += STACK_ARG_SIZE((*ptr)->size);
217217+ }
218218+#endif
219219+ }
220220+221221+ cif->bytes = bytes;
222222+223223+ /* Perform machine dependent cif processing */
224224+ return ffi_prep_cif_machdep(cif);
225225+}
226226+#endif /* not __CRIS__ */
+362
src/libffi/include/ffi.h
···11+/* -----------------------------------------------------------------*-C-*-
22+ libffi PyOBJC - Copyright (c) 1996-2003 Red Hat, Inc.
33+44+ Permission is hereby granted, free of charge, to any person obtaining
55+ a copy of this software and associated documentation files (the
66+ ``Software''), to deal in the Software without restriction, including
77+ without limitation the rights to use, copy, modify, merge, publish,
88+ distribute, sublicense, and/or sell copies of the Software, and to
99+ permit persons to whom the Software is furnished to do so, subject to
1010+ the following conditions:
1111+1212+ The above copyright notice and this permission notice shall be included
1313+ in all copies or substantial portions of the Software.
1414+1515+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1616+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1717+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1818+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
1919+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2020+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2121+ OTHER DEALINGS IN THE SOFTWARE.
2222+2323+ ----------------------------------------------------------------------- */
2424+2525+/* -------------------------------------------------------------------
2626+ The basic API is described in the README file.
2727+2828+ The raw API is designed to bypass some of the argument packing
2929+ and unpacking on architectures for which it can be avoided.
3030+3131+ The closure API allows interpreted functions to be packaged up
3232+ inside a C function pointer, so that they can be called as C functions,
3333+ with no understanding on the client side that they are interpreted.
3434+ It can also be used in other cases in which it is necessary to package
3535+ up a user specified parameter and a function pointer as a single
3636+ function pointer.
3737+3838+ The closure API must be implemented in order to get its functionality,
3939+ e.g. for use by gij. Routines are provided to emulate the raw API
4040+ if the underlying platform doesn't allow faster implementation.
4141+4242+ More details on the raw and closure API can be found in:
4343+4444+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
4545+4646+ and
4747+4848+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
4949+ -------------------------------------------------------------------- */
5050+5151+#ifndef LIBFFI_H
5252+#define LIBFFI_H
5353+5454+#ifdef __cplusplus
5555+extern "C" {
5656+#endif
5757+5858+#include "fficonfig.h"
5959+6060+/* Specify which architecture libffi is configured for. */
6161+#ifdef MACOSX
6262+# if defined(__i386__) || defined(__x86_64__)
6363+# define X86_DARWIN
6464+# elif defined(__ppc__) || defined(__ppc64__)
6565+# define POWERPC_DARWIN
6666+# else
6767+# error "Unsupported MacOS X CPU type"
6868+# endif
6969+#else
7070+#error "Unsupported OS type"
7171+#endif
7272+7373+/* ---- System configuration information --------------------------------- */
7474+7575+#include "ffitarget.h"
7676+7777+#ifndef LIBFFI_ASM
7878+7979+#include <stddef.h>
8080+#include <limits.h>
8181+8282+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
8383+ But we can find it either under the correct ANSI name, or under GNU
8484+ C's internal name. */
8585+#ifdef LONG_LONG_MAX
8686+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
8787+#else
8888+# ifdef LLONG_MAX
8989+# define FFI_LONG_LONG_MAX LLONG_MAX
9090+# else
9191+# ifdef __GNUC__
9292+# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
9393+# endif
9494+# endif
9595+#endif
9696+9797+#if SCHAR_MAX == 127
9898+# define ffi_type_uchar ffi_type_uint8
9999+# define ffi_type_schar ffi_type_sint8
100100+#else
101101+#error "char size not supported"
102102+#endif
103103+104104+#if SHRT_MAX == 32767
105105+# define ffi_type_ushort ffi_type_uint16
106106+# define ffi_type_sshort ffi_type_sint16
107107+#elif SHRT_MAX == 2147483647
108108+# define ffi_type_ushort ffi_type_uint32
109109+# define ffi_type_sshort ffi_type_sint32
110110+#else
111111+#error "short size not supported"
112112+#endif
113113+114114+#if INT_MAX == 32767
115115+# define ffi_type_uint ffi_type_uint16
116116+# define ffi_type_sint ffi_type_sint16
117117+#elif INT_MAX == 2147483647
118118+# define ffi_type_uint ffi_type_uint32
119119+# define ffi_type_sint ffi_type_sint32
120120+#elif INT_MAX == 9223372036854775807
121121+# define ffi_type_uint ffi_type_uint64
122122+# define ffi_type_sint ffi_type_sint64
123123+#else
124124+#error "int size not supported"
125125+#endif
126126+127127+#if LONG_MAX == 2147483647
128128+# if FFI_LONG_LONG_MAX != 9223372036854775807
129129+# error "no 64-bit data type supported"
130130+# endif
131131+#elif LONG_MAX != 9223372036854775807
132132+#error "long size not supported"
133133+#endif
134134+135135+#if LONG_MAX == 2147483647
136136+# define ffi_type_ulong ffi_type_uint32
137137+# define ffi_type_slong ffi_type_sint32
138138+#elif LONG_MAX == 9223372036854775807
139139+# define ffi_type_ulong ffi_type_uint64
140140+# define ffi_type_slong ffi_type_sint64
141141+#else
142142+#error "long size not supported"
143143+#endif
144144+145145+/* The closure code assumes that this works on pointers, i.e. a size_t
146146+ can hold a pointer. */
147147+148148+typedef struct _ffi_type {
149149+ size_t size;
150150+ unsigned short alignment;
151151+ unsigned short type;
152152+/*@null@*/ struct _ffi_type** elements;
153153+} ffi_type;
154154+155155+/* These are defined in types.c */
156156+extern ffi_type ffi_type_void;
157157+extern ffi_type ffi_type_uint8;
158158+extern ffi_type ffi_type_sint8;
159159+extern ffi_type ffi_type_uint16;
160160+extern ffi_type ffi_type_sint16;
161161+extern ffi_type ffi_type_uint32;
162162+extern ffi_type ffi_type_sint32;
163163+extern ffi_type ffi_type_uint64;
164164+extern ffi_type ffi_type_sint64;
165165+extern ffi_type ffi_type_float;
166166+extern ffi_type ffi_type_double;
167167+extern ffi_type ffi_type_longdouble;
168168+extern ffi_type ffi_type_pointer;
169169+170170+typedef enum ffi_status {
171171+ FFI_OK = 0,
172172+ FFI_BAD_TYPEDEF,
173173+ FFI_BAD_ABI
174174+} ffi_status;
175175+176176+typedef unsigned FFI_TYPE;
177177+178178+typedef struct ffi_cif {
179179+ ffi_abi abi;
180180+ unsigned nargs;
181181+/*@dependent@*/ ffi_type** arg_types;
182182+/*@dependent@*/ ffi_type* rtype;
183183+ unsigned bytes;
184184+ unsigned flags;
185185+#ifdef FFI_EXTRA_CIF_FIELDS
186186+ FFI_EXTRA_CIF_FIELDS;
187187+#endif
188188+} ffi_cif;
189189+190190+/* ---- Definitions for the raw API -------------------------------------- */
191191+192192+#ifndef FFI_SIZEOF_ARG
193193+# if LONG_MAX == 2147483647
194194+# define FFI_SIZEOF_ARG 4
195195+# elif LONG_MAX == 9223372036854775807
196196+# define FFI_SIZEOF_ARG 8
197197+# endif
198198+#endif
199199+200200+typedef union {
201201+ ffi_sarg sint;
202202+ ffi_arg uint;
203203+ float flt;
204204+ char data[FFI_SIZEOF_ARG];
205205+ void* ptr;
206206+} ffi_raw;
207207+208208+void
209209+ffi_raw_call(
210210+/*@dependent@*/ ffi_cif* cif,
211211+ void (*fn)(void),
212212+/*@out@*/ void* rvalue,
213213+/*@dependent@*/ ffi_raw* avalue);
214214+215215+void
216216+ffi_ptrarray_to_raw(
217217+ ffi_cif* cif,
218218+ void** args,
219219+ ffi_raw* raw);
220220+221221+void
222222+ffi_raw_to_ptrarray(
223223+ ffi_cif* cif,
224224+ ffi_raw* raw,
225225+ void** args);
226226+227227+size_t
228228+ffi_raw_size(
229229+ ffi_cif* cif);
230230+231231+/* This is analogous to the raw API, except it uses Java parameter
232232+ packing, even on 64-bit machines. I.e. on 64-bit machines
233233+ longs and doubles are followed by an empty 64-bit word. */
234234+void
235235+ffi_java_raw_call(
236236+/*@dependent@*/ ffi_cif* cif,
237237+ void (*fn)(void),
238238+/*@out@*/ void* rvalue,
239239+/*@dependent@*/ ffi_raw* avalue);
240240+241241+void
242242+ffi_java_ptrarray_to_raw(
243243+ ffi_cif* cif,
244244+ void** args,
245245+ ffi_raw* raw);
246246+247247+void
248248+ffi_java_raw_to_ptrarray(
249249+ ffi_cif* cif,
250250+ ffi_raw* raw,
251251+ void** args);
252252+253253+size_t
254254+ffi_java_raw_size(
255255+ ffi_cif* cif);
256256+257257+/* ---- Definitions for closures ----------------------------------------- */
258258+259259+#if FFI_CLOSURES
260260+261261+typedef struct ffi_closure {
262262+ char tramp[FFI_TRAMPOLINE_SIZE];
263263+ ffi_cif* cif;
264264+ void (*fun)(ffi_cif*,void*,void**,void*);
265265+ void* user_data;
266266+} ffi_closure;
267267+268268+ffi_status
269269+ffi_prep_closure(
270270+ ffi_closure* closure,
271271+ ffi_cif* cif,
272272+ void (*fun)(ffi_cif*,void*,void**,void*),
273273+ void* user_data);
274274+275275+typedef struct ffi_raw_closure {
276276+ char tramp[FFI_TRAMPOLINE_SIZE];
277277+ ffi_cif* cif;
278278+279279+#if !FFI_NATIVE_RAW_API
280280+ /* if this is enabled, then a raw closure has the same layout
281281+ as a regular closure. We use this to install an intermediate
282282+ handler to do the transaltion, void** -> ffi_raw*. */
283283+ void (*translate_args)(ffi_cif*,void*,void**,void*);
284284+ void* this_closure;
285285+#endif
286286+287287+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
288288+ void* user_data;
289289+} ffi_raw_closure;
290290+291291+ffi_status
292292+ffi_prep_raw_closure(
293293+ ffi_raw_closure* closure,
294294+ ffi_cif* cif,
295295+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
296296+ void* user_data);
297297+298298+ffi_status
299299+ffi_prep_java_raw_closure(
300300+ ffi_raw_closure* closure,
301301+ ffi_cif* cif,
302302+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
303303+ void* user_data);
304304+305305+#else
306306+#error FFI_CLOSURES not defined
307307+#endif
308308+309309+/* ---- Public interface definition -------------------------------------- */
310310+311311+ffi_status
312312+ffi_prep_cif(
313313+/*@out@*/ /*@partial@*/ ffi_cif* cif,
314314+ ffi_abi abi,
315315+ unsigned int nargs,
316316+/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype,
317317+/*@dependent@*/ ffi_type** atypes);
318318+319319+void
320320+ffi_call(
321321+/*@dependent@*/ ffi_cif* cif,
322322+ void (*fn)(void),
323323+/*@out@*/ void* rvalue,
324324+/*@dependent@*/ void** avalue);
325325+326326+/* Useful for eliminating compiler warnings */
327327+#define FFI_FN(f) ((void (*)(void))f)
328328+329329+#endif // #ifndef LIBFFI_ASM
330330+/* ---- Definitions shared with assembly code ---------------------------- */
331331+332332+/* If these change, update src/mips/ffitarget.h. */
333333+#define FFI_TYPE_VOID 0
334334+#define FFI_TYPE_INT 1
335335+#define FFI_TYPE_FLOAT 2
336336+#define FFI_TYPE_DOUBLE 3
337337+338338+#ifdef HAVE_LONG_DOUBLE
339339+# define FFI_TYPE_LONGDOUBLE 4
340340+#else
341341+# define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
342342+#endif
343343+344344+#define FFI_TYPE_UINT8 5
345345+#define FFI_TYPE_SINT8 6
346346+#define FFI_TYPE_UINT16 7
347347+#define FFI_TYPE_SINT16 8
348348+#define FFI_TYPE_UINT32 9
349349+#define FFI_TYPE_SINT32 10
350350+#define FFI_TYPE_UINT64 11
351351+#define FFI_TYPE_SINT64 12
352352+#define FFI_TYPE_STRUCT 13
353353+#define FFI_TYPE_POINTER 14
354354+355355+/* This should always refer to the last type code (for sanity checks) */
356356+#define FFI_TYPE_LAST FFI_TYPE_POINTER
357357+358358+#ifdef __cplusplus
359359+}
360360+#endif
361361+362362+#endif // #ifndef LIBFFI_H
+98
src/libffi/include/ffi_common.h
···11+/* -----------------------------------------------------------------------
22+ ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
33+44+ Common internal definitions and macros. Only necessary for building
55+ libffi.
66+ ----------------------------------------------------------------------- */
77+88+#ifndef FFI_COMMON_H
99+#define FFI_COMMON_H
1010+1111+#ifdef __cplusplus
1212+extern "C" {
1313+#endif
1414+1515+#include "fficonfig.h"
1616+1717+/* Do not move this. Some versions of AIX are very picky about where
1818+ this is positioned. */
1919+#ifdef __GNUC__
2020+# define alloca __builtin_alloca
2121+#else
2222+# if HAVE_ALLOCA_H
2323+# include <alloca.h>
2424+# else
2525+# ifdef _AIX
2626+# pragma alloca
2727+# else
2828+# ifndef alloca /* predefined by HP cc +Olibcalls */
2929+char* alloca();
3030+# endif
3131+# endif
3232+# endif
3333+#endif
3434+3535+/* Check for the existence of memcpy. */
3636+#if STDC_HEADERS
3737+# include <string.h>
3838+#else
3939+# ifndef HAVE_MEMCPY
4040+# define memcpy(d, s, n) bcopy((s), (d), (n))
4141+# endif
4242+#endif
4343+4444+#ifdef FFI_DEBUG
4545+#include <stdio.h>
4646+4747+/*@exits@*/ void
4848+ffi_assert(
4949+/*@temp@*/ char* expr,
5050+/*@temp@*/ char* file,
5151+ int line);
5252+void
5353+ffi_stop_here(void);
5454+void
5555+ffi_type_test(
5656+/*@temp@*/ /*@out@*/ ffi_type* a,
5757+/*@temp@*/ char* file,
5858+ int line);
5959+6060+# define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
6161+# define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
6262+# define FFI_ASSERT_VALID_TYPE(x) ffi_type_test(x, __FILE__, __LINE__)
6363+#else
6464+# define FFI_ASSERT(x)
6565+# define FFI_ASSERT_AT(x, f, l)
6666+# define FFI_ASSERT_VALID_TYPE(x)
6767+#endif // #ifdef FFI_DEBUG
6868+6969+#define ALIGN(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1))
7070+7171+/* Perform machine dependent cif processing */
7272+ffi_status
7373+ffi_prep_cif_machdep(
7474+ ffi_cif* cif);
7575+7676+/* Extended cif, used in callback from assembly routine */
7777+typedef struct extended_cif {
7878+/*@dependent@*/ ffi_cif* cif;
7979+/*@dependent@*/ void* rvalue;
8080+/*@dependent@*/ void** avalue;
8181+} extended_cif;
8282+8383+/* Terse sized type definitions. */
8484+typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
8585+typedef signed int SINT8 __attribute__((__mode__(__QI__)));
8686+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
8787+typedef signed int SINT16 __attribute__((__mode__(__HI__)));
8888+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
8989+typedef signed int SINT32 __attribute__((__mode__(__SI__)));
9090+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
9191+typedef signed int SINT64 __attribute__((__mode__(__DI__)));
9292+typedef float FLOAT32;
9393+9494+#ifdef __cplusplus
9595+}
9696+#endif
9797+9898+#endif // #ifndef FFI_COMMON_H
+154
src/libffi/include/fficonfig.h
···11+/* Manually created fficonfig.h for Darwin on PowerPC or Intel
22+33+ This file is manually generated to do away with the need for autoconf and
44+ therefore make it easier to cross-compile and build fat binaries.
55+66+ NOTE: This file was added by PyObjC.
77+*/
88+99+#if defined(__APPLE__) && defined(__MACH__) && !defined(MACOSX)
1010+ #define MACOSX
1111+#endif
1212+1313+#ifndef MACOSX
1414+#error "This file is only supported on Mac OS X"
1515+#endif
1616+1717+#if defined(__i386__)
1818+# define BYTEORDER 1234
1919+# undef HOST_WORDS_BIG_ENDIAN
2020+# undef WORDS_BIGENDIAN
2121+# define SIZEOF_DOUBLE 8
2222+# define HAVE_LONG_DOUBLE 1
2323+# define SIZEOF_LONG_DOUBLE 16
2424+2525+#elif defined(__x86_64__)
2626+# define BYTEORDER 1234
2727+# undef HOST_WORDS_BIG_ENDIAN
2828+# undef WORDS_BIGENDIAN
2929+# define SIZEOF_DOUBLE 8
3030+# define HAVE_LONG_DOUBLE 1
3131+# define SIZEOF_LONG_DOUBLE 16
3232+3333+#elif defined(__ppc__)
3434+# define BYTEORDER 4321
3535+# define HOST_WORDS_BIG_ENDIAN 1
3636+# define WORDS_BIGENDIAN 1
3737+# define SIZEOF_DOUBLE 8
3838+# if __GNUC__ >= 4
3939+# define HAVE_LONG_DOUBLE 1
4040+# define SIZEOF_LONG_DOUBLE 16
4141+# else
4242+# undef HAVE_LONG_DOUBLE
4343+# define SIZEOF_LONG_DOUBLE 8
4444+# endif
4545+4646+#elif defined(__ppc64__)
4747+# define BYTEORDER 4321
4848+# define HOST_WORDS_BIG_ENDIAN 1
4949+# define WORDS_BIGENDIAN 1
5050+# define SIZEOF_DOUBLE 8
5151+# define HAVE_LONG_DOUBLE 1
5252+# define SIZEOF_LONG_DOUBLE 16
5353+5454+#else
5555+#error "Unknown CPU type"
5656+#endif
5757+5858+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
5959+ systems. This function is required for `alloca.c' support on those systems. */
6060+#undef CRAY_STACKSEG_END
6161+6262+/* Define to 1 if using `alloca.c'. */
6363+/* #undef C_ALLOCA */
6464+6565+/* Define to the flags needed for the .section .eh_frame directive. */
6666+#define EH_FRAME_FLAGS "aw"
6767+6868+/* Define this if you want extra debugging. */
6969+#undef FFI_DEBUG
7070+7171+/* Define this is you do not want support for the raw API. */
7272+#define FFI_NO_RAW_API 1
7373+7474+/* Define this if you do not want support for aggregate types. */
7575+/* #undef FFI_NO_STRUCTS */
7676+7777+/* Define to 1 if you have `alloca', as a function or macro. */
7878+#define HAVE_ALLOCA 1
7979+8080+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
8181+#define HAVE_ALLOCA_H 1
8282+8383+/* Define if your assembler supports .register. */
8484+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
8585+8686+/* Define if your assembler and linker support unaligned PC relative relocs. */
8787+/* #undef HAVE_AS_SPARC_UA_PCREL */
8888+8989+/* Define to 1 if you have the `memcpy' function. */
9090+#define HAVE_MEMCPY 1
9191+9292+/* Define if mmap with MAP_ANON(YMOUS) works. */
9393+#define HAVE_MMAP_ANON 1
9494+9595+/* Define if mmap of /dev/zero works. */
9696+/* #undef HAVE_MMAP_DEV_ZERO */
9797+9898+/* Define if read-only mmap of a plain file works. */
9999+#define HAVE_MMAP_FILE 1
100100+101101+/* Define if .eh_frame sections should be read-only. */
102102+/* #undef HAVE_RO_EH_FRAME */
103103+104104+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
105105+/* #undef NO_MINUS_C_MINUS_O */
106106+107107+/* Name of package */
108108+#define PACKAGE "libffi"
109109+110110+/* Define to the address where bug reports for this package should be sent. */
111111+#define PACKAGE_BUGREPORT "http://gcc.gnu.org/bugs.html"
112112+113113+/* Define to the full name of this package. */
114114+#define PACKAGE_NAME "libffi"
115115+116116+/* Define to the full name and version of this package. */
117117+#define PACKAGE_STRING "libffi 2.1"
118118+119119+/* Define to the one symbol short name of this package. */
120120+#define PACKAGE_TARNAME "libffi"
121121+122122+/* Define to the version of this package. */
123123+#define PACKAGE_VERSION "2.1"
124124+125125+/* If using the C implementation of alloca, define if you know the
126126+ direction of stack growth for your system; otherwise it will be
127127+ automatically deduced at run-time.
128128+ STACK_DIRECTION > 0 => grows toward higher addresses
129129+ STACK_DIRECTION < 0 => grows toward lower addresses
130130+ STACK_DIRECTION = 0 => direction of growth unknown */
131131+/* #undef STACK_DIRECTION */
132132+133133+/* Define to 1 if you have the ANSI C header files. */
134134+#define STDC_HEADERS 1
135135+136136+/* Define this if you are using Purify and want to suppress spurious messages. */
137137+/* #undef USING_PURIFY */
138138+139139+/* Version number of package */
140140+#define VERSION "2.1-pyobjc"
141141+142142+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
143143+# ifdef LIBFFI_ASM
144144+# define FFI_HIDDEN(name) .hidden name
145145+# else
146146+# define FFI_HIDDEN __attribute__((visibility ("hidden")))
147147+# endif
148148+#else
149149+# ifdef LIBFFI_ASM
150150+# define FFI_HIDDEN(name)
151151+# else
152152+# define FFI_HIDDEN
153153+# endif
154154+#endif
+13
src/libffi/include/ffitarget.h
···11+/* Dispatch to the right ffitarget file. This file is PyObjC specific; in a
22+ normal build, the build environment copies the file to the right location or
33+ sets up the right include flags. We want to do neither because that would
44+ make building fat binaries harder.
55+*/
66+77+#if defined(__i386__) || defined(__x86_64__)
88+#include "x86-ffitarget.h"
99+#elif defined(__ppc__) || defined(__ppc64__)
1010+#include "ppc-ffitarget.h"
1111+#else
1212+#error "Unsupported CPU type"
1313+#endif
+104
src/libffi/include/ppc-ffitarget.h
···11+/* -----------------------------------------------------------------*-C-*-
22+ ppc-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
33+ Target configuration macros for PowerPC.
44+55+ Permission is hereby granted, free of charge, to any person obtaining
66+ a copy of this software and associated documentation files (the
77+ ``Software''), to deal in the Software without restriction, including
88+ without limitation the rights to use, copy, modify, merge, publish,
99+ distribute, sublicense, and/or sell copies of the Software, and to
1010+ permit persons to whom the Software is furnished to do so, subject to
1111+ the following conditions:
1212+1313+ The above copyright notice and this permission notice shall be included
1414+ in all copies or substantial portions of the Software.
1515+1616+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1717+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1818+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1919+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2020+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2121+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2222+ OTHER DEALINGS IN THE SOFTWARE.
2323+ ----------------------------------------------------------------------- */
2424+2525+#ifndef LIBFFI_TARGET_H
2626+#define LIBFFI_TARGET_H
2727+2828+/* ---- System specific configurations ----------------------------------- */
2929+3030+#if (defined(POWERPC) && defined(__powerpc64__)) || \
3131+ (defined(POWERPC_DARWIN) && defined(__ppc64__))
3232+#define POWERPC64
3333+#endif
3434+3535+#ifndef LIBFFI_ASM
3636+3737+typedef unsigned long ffi_arg;
3838+typedef signed long ffi_sarg;
3939+4040+typedef enum ffi_abi {
4141+ FFI_FIRST_ABI = 0,
4242+4343+#ifdef POWERPC
4444+ FFI_SYSV,
4545+ FFI_GCC_SYSV,
4646+ FFI_LINUX64,
4747+# ifdef POWERPC64
4848+ FFI_DEFAULT_ABI = FFI_LINUX64,
4949+# else
5050+ FFI_DEFAULT_ABI = FFI_GCC_SYSV,
5151+# endif
5252+#endif
5353+5454+#ifdef POWERPC_AIX
5555+ FFI_AIX,
5656+ FFI_DARWIN,
5757+ FFI_DEFAULT_ABI = FFI_AIX,
5858+#endif
5959+6060+#ifdef POWERPC_DARWIN
6161+ FFI_AIX,
6262+ FFI_DARWIN,
6363+ FFI_DEFAULT_ABI = FFI_DARWIN,
6464+#endif
6565+6666+#ifdef POWERPC_FREEBSD
6767+ FFI_SYSV,
6868+ FFI_GCC_SYSV,
6969+ FFI_LINUX64,
7070+ FFI_DEFAULT_ABI = FFI_SYSV,
7171+#endif
7272+7373+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
7474+} ffi_abi;
7575+7676+#endif // #ifndef LIBFFI_ASM
7777+7878+/* ---- Definitions for closures ----------------------------------------- */
7979+8080+#define FFI_CLOSURES 1
8181+#define FFI_NATIVE_RAW_API 0
8282+8383+/* Needed for FFI_SYSV small structure returns. */
8484+#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST)
8585+8686+#if defined(POWERPC64) /*|| defined(POWERPC_AIX)*/
8787+# define FFI_TRAMPOLINE_SIZE 48
8888+#elif defined(POWERPC_AIX)
8989+# define FFI_TRAMPOLINE_SIZE 24
9090+#else
9191+# define FFI_TRAMPOLINE_SIZE 40
9292+#endif
9393+9494+#ifndef LIBFFI_ASM
9595+# if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
9696+typedef struct ffi_aix_trampoline_struct {
9797+ void* code_pointer; /* Pointer to ffi_closure_ASM */
9898+ void* toc; /* TOC */
9999+ void* static_chain; /* Pointer to closure */
100100+} ffi_aix_trampoline_struct;
101101+# endif
102102+#endif // #ifndef LIBFFI_ASM
103103+104104+#endif // #ifndef LIBFFI_TARGET_H
+88
src/libffi/include/x86-ffitarget.h
···11+/* -----------------------------------------------------------------*-C-*-
22+ x86-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
33+ Target configuration macros for x86 and x86-64.
44+55+ Permission is hereby granted, free of charge, to any person obtaining
66+ a copy of this software and associated documentation files (the
77+ ``Software''), to deal in the Software without restriction, including
88+ without limitation the rights to use, copy, modify, merge, publish,
99+ distribute, sublicense, and/or sell copies of the Software, and to
1010+ permit persons to whom the Software is furnished to do so, subject to
1111+ the following conditions:
1212+1313+ The above copyright notice and this permission notice shall be included
1414+ in all copies or substantial portions of the Software.
1515+1616+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1717+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1818+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1919+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2020+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2121+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2222+ OTHER DEALINGS IN THE SOFTWARE.
2323+2424+ ----------------------------------------------------------------------- */
2525+2626+#ifndef LIBFFI_TARGET_H
2727+#define LIBFFI_TARGET_H
2828+2929+/* ---- System specific configurations ----------------------------------- */
3030+3131+#if defined(X86_64) && defined(__i386__)
3232+# undef X86_64
3333+# define X86
3434+#endif
3535+3636+#if defined(__x86_64__)
3737+# ifndef X86_64
3838+# define X86_64
3939+# endif
4040+#endif
4141+4242+/* ---- Generic type definitions ----------------------------------------- */
4343+4444+#ifndef LIBFFI_ASM
4545+4646+typedef unsigned long ffi_arg;
4747+typedef signed long ffi_sarg;
4848+4949+typedef enum ffi_abi {
5050+ FFI_FIRST_ABI = 0,
5151+5252+ /* ---- Intel x86 Win32 ---------- */
5353+#ifdef X86_WIN32
5454+ FFI_SYSV,
5555+ FFI_STDCALL,
5656+ /* TODO: Add fastcall support for the sake of completeness */
5757+ FFI_DEFAULT_ABI = FFI_SYSV,
5858+#endif
5959+6060+ /* ---- Intel x86 and AMD x86-64 - */
6161+#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
6262+ FFI_SYSV,
6363+ FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
6464+# ifdef __i386__
6565+ FFI_DEFAULT_ABI = FFI_SYSV,
6666+# else
6767+ FFI_DEFAULT_ABI = FFI_UNIX64,
6868+# endif
6969+#endif
7070+7171+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
7272+} ffi_abi;
7373+7474+#endif // #ifndef LIBFFI_ASM
7575+7676+/* ---- Definitions for closures ----------------------------------------- */
7777+7878+#define FFI_CLOSURES 1
7979+8080+#if defined(X86_64) || (defined(__x86_64__) && defined(X86_DARWIN))
8181+# define FFI_TRAMPOLINE_SIZE 24
8282+# define FFI_NATIVE_RAW_API 0
8383+#else
8484+# define FFI_TRAMPOLINE_SIZE 10
8585+# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
8686+#endif
8787+8888+#endif // #ifndef LIBFFI_TARGET_H
···11+.Dd July 20, 2007
22+.Dt FFI 3
33+.Os Darwin
44+.Sh NAME
55+.Nm FFI
66+.Nd Foreign Function Interface
77+.Sh LIBRARY
88+libffi, -lffi
99+.Sh SYNOPSIS
1010+.In ffi/ffi.h
1111+.Ft ffi_status
1212+.Fo ffi_prep_cif
1313+.Fa "ffi_cif *cif"
1414+.Fa "ffi_abi abi"
1515+.Fa "unsigned int nargs"
1616+.Fa "ffi_type *rtype"
1717+.Fa "ffi_type **atypes"
1818+.Fc
1919+.Ft ffi_status
2020+.Fo ffi_prep_closure
2121+.Fa "ffi_closure *closure"
2222+.Fa "ffi_cif *cif"
2323+.Fa "void (*fun)(ffi_cif*,void*,void**,void*)"
2424+.Fa "void *user_data"
2525+.Fc
2626+.Ft void
2727+.Fo ffi_call
2828+.Fa "ffi_cif *cif"
2929+.Fa "void (*fn)(void)"
3030+.Fa "void *rvalue"
3131+.Fa "void **avalue"
3232+.Fc
3333+.Sh DESCRIPTION
3434+The foreign function interface provides a mechanism by which a function can
3535+generate a call to another function at runtime without requiring knowledge of
3636+the called function's interface at compile time.
3737+.Sh SEE ALSO
3838+.Xr ffi_prep_cif 3 ,
3939+.Xr ffi_prep_closure 3 ,
4040+.Xr ffi_call 3
+106
src/libffi/man/ffi_call.3
···11+.Dd July 20, 2007
22+.Dt ffi_call 3
33+.Os Darwin
44+.Sh NAME
55+.Nm ffi_call
66+.Nd Invoke a foreign function.
77+.Sh SYNOPSIS
88+.In ffi/ffi.h
99+.Ft void
1010+.Fo ffi_call
1111+.Fa "ffi_cif *cif"
1212+.Fa "void (*fn)(void)"
1313+.Fa "void *rvalue"
1414+.Fa "void **avalue"
1515+.Fc
1616+.Sh DESCRIPTION
1717+The
1818+.Nm ffi_call
1919+function provides a simple mechanism for invoking a function without
2020+requiring knowledge of the function's interface at compile time.
2121+.Fa fn
2222+is called with the values retrieved from the pointers in the
2323+.Fa avalue
2424+array. The return value from
2525+.Fa fn
2626+is placed in storage pointed to by
2727+.Fa rvalue .
2828+.Fa cif
2929+contains information describing the data types, sizes and alignments of the
3030+arguments to and return value from
3131+.Fa fn ,
3232+and must be initialized with
3333+.Nm ffi_prep_cif
3434+before it is used with
3535+.Nm ffi_call .
3636+.Pp
3737+.Fa rvalue
3838+must point to storage that is sizeof(long) or larger. For smaller
3939+return value sizes, the
4040+.Nm ffi_arg
4141+or
4242+.Nm ffi_sarg
4343+integral type must be used to hold
4444+the return value.
4545+.Sh EXAMPLES
4646+.Bd -literal
4747+#define MACOSX // for fficonfig.h on Darwin
4848+4949+#include <ffi/ffi.h>
5050+#include <stdio.h>
5151+5252+unsigned char
5353+foo(unsigned int, float);
5454+5555+int
5656+main(int argc, const char **argv)
5757+{
5858+ ffi_cif cif;
5959+ ffi_type *arg_types[2];
6060+ void *arg_values[2];
6161+ ffi_status status;
6262+6363+ // Because the return value from foo() is smaller than sizeof(long), it
6464+ // must be passed as ffi_arg or ffi_sarg.
6565+ ffi_arg result;
6666+6767+ // Specify the data type of each argument. Available types are defined
6868+ // in <ffi/ffi.h>.
6969+ arg_types[0] = &ffi_type_uint;
7070+ arg_types[1] = &ffi_type_float;
7171+7272+ // Prepare the ffi_cif structure.
7373+ if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
7474+ 2, &ffi_type_uint8, arg_types)) != FFI_OK)
7575+ {
7676+ // Handle the ffi_status error.
7777+ }
7878+7979+ // Specify the values of each argument.
8080+ unsigned int arg1 = 42;
8181+ float arg2 = 5.1;
8282+8383+ arg_values[0] = &arg1;
8484+ arg_values[1] = &arg2;
8585+8686+ // Invoke the function.
8787+ ffi_call(&cif, FFI_FN(foo), &result, arg_values);
8888+8989+ // The ffi_arg 'result' now contains the unsigned char returned from foo(),
9090+ // which can be accessed by a typecast.
9191+ printf("result is %hhu", (unsigned char)result);
9292+9393+ return 0;
9494+}
9595+9696+// The target function.
9797+unsigned char
9898+foo(unsigned int x, float y)
9999+{
100100+ unsigned char result = x - y;
101101+ return result;
102102+}
103103+.Ed
104104+.Sh SEE ALSO
105105+.Xr ffi 3 ,
106106+.Xr ffi_prep_cif 3
+71
src/libffi/man/ffi_prep_cif.3
···11+.Dd July 20, 2007
22+.Dt ffi_prep_cif 3
33+.Os Darwin
44+.Sh NAME
55+.Nm ffi_prep_cif
66+.Nd Prepare a
77+.Nm ffi_cif
88+structure for use with
99+.Nm ffi_call
1010+or
1111+.Nm ffi_prep_closure .
1212+.Sh SYNOPSIS
1313+.In ffi/ffi.h
1414+.Ft ffi_status
1515+.Fo ffi_prep_cif
1616+.Fa "ffi_cif *cif"
1717+.Fa "ffi_abi abi"
1818+.Fa "unsigned int nargs"
1919+.Fa "ffi_type *rtype"
2020+.Fa "ffi_type **atypes"
2121+.Fc
2222+.Sh DESCRIPTION
2323+The
2424+.Nm ffi_prep_cif
2525+function prepares a
2626+.Nm ffi_cif
2727+structure for use with
2828+.Nm ffi_call
2929+or
3030+.Nm ffi_prep_closure .
3131+.Fa abi
3232+specifies a set of calling conventions to use.
3333+.Fa atypes
3434+is an array of
3535+.Fa nargs
3636+pointers to
3737+.Nm ffi_type
3838+structs that describe the data type, size and alignment of each argument.
3939+.Fa rtype
4040+points to an
4141+.Nm ffi_type
4242+that describes the data type, size and alignment of the
4343+return value.
4444+.Sh RETURN VALUES
4545+Upon successful completion,
4646+.Nm ffi_prep_cif
4747+returns
4848+.Nm FFI_OK .
4949+It will return
5050+.Nm FFI_BAD_TYPEDEF
5151+if
5252+.Fa cif
5353+is
5454+.Nm NULL
5555+or
5656+.Fa atypes
5757+or
5858+.Fa rtype
5959+is malformed. If
6060+.Fa abi
6161+does not refer to a valid ABI,
6262+.Nm FFI_BAD_ABI
6363+will be returned. Available ABIs are
6464+defined in
6565+.Nm <ffi/ppc-ffitarget.h>
6666+and
6767+.Nm <ffi/x86-ffitarget.h> .
6868+.Sh SEE ALSO
6969+.Xr ffi 3 ,
7070+.Xr ffi_call 3 ,
7171+.Xr ffi_prep_closure 3
+162
src/libffi/man/ffi_prep_closure.3
···11+.Dd July 20, 2007
22+.Dt ffi_prep_closure 3
33+.Os Darwin
44+.Sh NAME
55+.Nm ffi_prep_closure
66+.Nd Prepare a
77+.Nm ffi_closure
88+for execution.
99+.Sh SYNOPSIS
1010+.In ffi/ffi.h
1111+.Ft ffi_status
1212+.Fo ffi_prep_closure
1313+.Fa "ffi_closure *closure"
1414+.Fa "ffi_cif *cif"
1515+.Fa "void (*fun)(ffi_cif*,void*,void**,void*)"
1616+.Fa "void *user_data"
1717+.Fc
1818+.Sh DESCRIPTION
1919+.Fa closure
2020+is prepared to execute
2121+.Fa fun .
2222+.Fa cif
2323+contains information describing the data types, sizes and alignments of the
2424+arguments to and return value from the function that will be called from
2525+.Fa fun ,
2626+and must be initialized with
2727+.Nm ffi_prep_cif
2828+before it is used with
2929+.Nm ffi_prep_closure .
3030+.Fa user_data
3131+may point to additional data to be used in
3232+.Fa fun .
3333+If no additional data is needed,
3434+.Fa user_data
3535+may be
3636+.Nm NULL .
3737+When
3838+.Fa closure
3939+is invoked,
4040+.Fa fun
4141+is called with
4242+.Fa cif ,
4343+an array of pointers to arguments, a pointer to a return value, and
4444+.Fa user_data .
4545+.Pp
4646+Some architectures do not allow the execution of data by default. In such cases,
4747+it is necessary to manually alter the permissions of the page that contains
4848+.Fa closure
4949+prior to its execution.
5050+.Sh RETURN VALUES
5151+Upon successful completion,
5252+.Nm ffi_prep_closure
5353+returns
5454+.Nm FFI_OK .
5555+If the ABI specified in
5656+.Fa cif
5757+does not refer to a valid ABI,
5858+.Nm FFI_BAD_ABI
5959+will be returned. Available ABIs are
6060+defined in
6161+.Nm <ffi/ppc-ffitarget.h>
6262+and
6363+.Nm <ffi/x86-ffitarget.h> .
6464+.Sh EXAMPLES
6565+.Bd -literal
6666+#define MACOSX // for fficonfig.h on Darwin
6767+6868+#include <ffi/ffi.h>
6969+#include <sys/mman.h> // for mmap()
7070+7171+unsigned char
7272+foo(unsigned int, float);
7373+7474+static void
7575+foo_closure(ffi_cif*, void*, void**, void*);
7676+7777+int
7878+main(int argc, const char **argv)
7979+{
8080+ ffi_cif cif;
8181+ ffi_closure *closure;
8282+ ffi_type *arg_types[2];
8383+ ffi_arg result;
8484+ ffi_status status;
8585+8686+ // Specify the data type of each argument. Available types are defined
8787+ // in <ffi/ffi.h>.
8888+ arg_types[0] = &ffi_type_uint;
8989+ arg_types[1] = &ffi_type_float;
9090+9191+ // Allocate a page to hold the closure with read and write permissions.
9292+ if ((closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
9393+ MAP_ANON | MAP_PRIVATE, -1, 0)) == (void*)-1)
9494+ {
9595+ // Check errno and handle the error.
9696+ }
9797+9898+ // Prepare the ffi_cif structure.
9999+ if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
100100+ 2, &ffi_type_uint8, arg_types)) != FFI_OK)
101101+ {
102102+ // Handle the ffi_status error.
103103+ }
104104+105105+ // Prepare the ffi_closure structure.
106106+ if ((status = ffi_prep_closure(closure, &cif, foo_closure, NULL)) != FFI_OK)
107107+ {
108108+ // Handle the ffi_status error.
109109+ }
110110+111111+ // Ensure that the closure will execute on all architectures.
112112+ if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
113113+ {
114114+ // Check errno and handle the error.
115115+ }
116116+117117+ // The closure is now ready to be executed, and can be saved for later
118118+ // execution if desired.
119119+120120+ // Invoke the closure.
121121+ result = ((unsigned char(*)(float, unsigned int))closure)(42, 5.1);
122122+123123+ // Free the memory associated with the closure.
124124+ if (munmap(closure, sizeof(closure)) == -1)
125125+ {
126126+ // Check errno and handle the error.
127127+ }
128128+129129+ return 0;
130130+}
131131+132132+// Invoking the closure transfers control to this function.
133133+static void
134134+foo_closure(ffi_cif* cif, void* result, void** args, void* userdata)
135135+{
136136+ // Access the arguments to be sent to foo().
137137+ float arg1 = *(float*)args[0];
138138+ unsigned int arg2 = *(unsigned int*)args[1];
139139+140140+ // Call foo() and save its return value.
141141+ unsigned char ret_val = foo(arg1, arg2);
142142+143143+ // Copy the returned value into result. Because the return value of foo()
144144+ // is smaller than sizeof(long), typecast it to ffi_arg. Use ffi_sarg
145145+ // instead for signed types.
146146+ *(ffi_arg*)result = (ffi_arg)ret_val;
147147+}
148148+149149+// The closed-over function.
150150+unsigned char
151151+foo(unsigned int x, float y)
152152+{
153153+ unsigned char result = x - y;
154154+ return result;
155155+}
156156+.Ed
157157+.Sh SEE ALSO
158158+.Xr ffi 3 ,
159159+.Xr ffi_prep_cif 3 ,
160160+.Xr mmap 2 ,
161161+.Xr munmap 2 ,
162162+.Xr mprotect 2
+365
src/libffi/powerpc/ppc-darwin.S
···11+#if defined(__ppc__) || defined(__ppc64__)
22+33+/* -----------------------------------------------------------------------
44+ ppc-darwin.S - Copyright (c) 2000 John Hornkvist
55+ Copyright (c) 2004 Free Software Foundation, Inc.
66+77+ PowerPC Assembly glue.
88+99+ Permission is hereby granted, free of charge, to any person obtaining
1010+ a copy of this software and associated documentation files (the
1111+ ``Software''), to deal in the Software without restriction, including
1212+ without limitation the rights to use, copy, modify, merge, publish,
1313+ distribute, sublicense, and/or sell copies of the Software, and to
1414+ permit persons to whom the Software is furnished to do so, subject to
1515+ the following conditions:
1616+1717+ The above copyright notice and this permission notice shall be included
1818+ in all copies or substantial portions of the Software.
1919+2020+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
2121+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2222+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2323+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
2424+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2525+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2626+ OTHER DEALINGS IN THE SOFTWARE.
2727+ ----------------------------------------------------------------------- */
2828+2929+#define LIBFFI_ASM
3030+3131+#include <fficonfig.h>
3232+#include <ffi.h>
3333+#include <ppc-darwin.h>
3434+#include <architecture/ppc/mode_independent_asm.h>
3535+3636+.text
3737+ .align 2
3838+.globl _ffi_prep_args
3939+4040+.text
4141+ .align 2
4242+.globl _ffi_call_DARWIN
4343+4444+.text
4545+ .align 2
4646+_ffi_call_DARWIN:
4747+LFB0:
4848+ mr r12,r8 /* We only need r12 until the call,
4949+ so it doesn't have to be saved. */
5050+5151+LFB1:
5252+ /* Save the old stack pointer as AP. */
5353+ mr r8,r1
5454+5555+LCFI0:
5656+#if defined(__ppc64__)
5757+ /* Allocate the stack space we need.
5858+ r4 (size of input data)
5959+ 48 bytes (linkage area)
6060+ 40 bytes (saved registers)
6161+ 8 bytes (extra FPR)
6262+ r4 + 96 bytes total
6363+ */
6464+6565+ addi r4,r4,-96 // Add our overhead.
6666+ li r0,-32 // Align to 32 bytes.
6767+ and r4,r4,r0
6868+#endif
6969+ stgux r1,r1,r4 // Grow the stack.
7070+ mflr r9
7171+7272+ /* Save registers we use. */
7373+#if defined(__ppc64__)
7474+ std r27,-40(r8)
7575+#endif
7676+ stg r28,MODE_CHOICE(-16,-32)(r8)
7777+ stg r29,MODE_CHOICE(-12,-24)(r8)
7878+ stg r30,MODE_CHOICE(-8,-16)(r8)
7979+ stg r31,MODE_CHOICE(-4,-8)(r8)
8080+ stg r9,SF_RETURN(r8) /* return address */
8181+#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */
8282+ stg r2,MODE_CHOICE(20,40)(r1)
8383+#endif
8484+8585+LCFI1:
8686+#if defined(__ppc64__)
8787+ mr r27,r3 // our extended_cif
8888+#endif
8989+ /* Save arguments over call. */
9090+ mr r31,r5 /* flags, */
9191+ mr r30,r6 /* rvalue, */
9292+ mr r29,r7 /* function address, */
9393+ mr r28,r8 /* our AP. */
9494+9595+LCFI2:
9696+ /* Call ffi_prep_args. */
9797+ mr r4,r1
9898+ li r9,0
9999+ mtctr r12 /* r12 holds address of _ffi_prep_args. */
100100+ bctrl
101101+#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */
102102+ lg r2,MODE_CHOICE(20,40)(r1)
103103+#endif
104104+105105+ /* Now do the call.
106106+ Set up cr1 with bits 4-7 of the flags. */
107107+ mtcrf 0x40,r31
108108+109109+ /* Load all those argument registers.
110110+ We have set up a nice stack frame, just load it into registers. */
111111+ lg r3,SF_ARG1(r1)
112112+ lg r4,SF_ARG2(r1)
113113+ lg r5,SF_ARG3(r1)
114114+ lg r6,SF_ARG4(r1)
115115+ nop
116116+ lg r7,SF_ARG5(r1)
117117+ lg r8,SF_ARG6(r1)
118118+ lg r9,SF_ARG7(r1)
119119+ lg r10,SF_ARG8(r1)
120120+121121+ /* Load all the FP registers. */
122122+ bf 6,L2 /* No floats to load. */
123123+#if defined(__ppc64__)
124124+ lfd f1,MODE_CHOICE(-16,-40)-(14*8)(r28)
125125+ lfd f2,MODE_CHOICE(-16,-40)-(13*8)(r28)
126126+ lfd f3,MODE_CHOICE(-16,-40)-(12*8)(r28)
127127+ lfd f4,MODE_CHOICE(-16,-40)-(11*8)(r28)
128128+ nop
129129+ lfd f5,MODE_CHOICE(-16,-40)-(10*8)(r28)
130130+ lfd f6,MODE_CHOICE(-16,-40)-(9*8)(r28)
131131+ lfd f7,MODE_CHOICE(-16,-40)-(8*8)(r28)
132132+ lfd f8,MODE_CHOICE(-16,-40)-(7*8)(r28)
133133+ nop
134134+ lfd f9,MODE_CHOICE(-16,-40)-(6*8)(r28)
135135+ lfd f10,MODE_CHOICE(-16,-40)-(5*8)(r28)
136136+ lfd f11,MODE_CHOICE(-16,-40)-(4*8)(r28)
137137+ lfd f12,MODE_CHOICE(-16,-40)-(3*8)(r28)
138138+ nop
139139+ lfd f13,MODE_CHOICE(-16,-40)-(2*8)(r28)
140140+ lfd f14,MODE_CHOICE(-16,-40)-(1*8)(r28)
141141+#elif defined(__ppc__)
142142+ lfd f1,MODE_CHOICE(-16,-40)-(13*8)(r28)
143143+ lfd f2,MODE_CHOICE(-16,-40)-(12*8)(r28)
144144+ lfd f3,MODE_CHOICE(-16,-40)-(11*8)(r28)
145145+ lfd f4,MODE_CHOICE(-16,-40)-(10*8)(r28)
146146+ nop
147147+ lfd f5,MODE_CHOICE(-16,-40)-(9*8)(r28)
148148+ lfd f6,MODE_CHOICE(-16,-40)-(8*8)(r28)
149149+ lfd f7,MODE_CHOICE(-16,-40)-(7*8)(r28)
150150+ lfd f8,MODE_CHOICE(-16,-40)-(6*8)(r28)
151151+ nop
152152+ lfd f9,MODE_CHOICE(-16,-40)-(5*8)(r28)
153153+ lfd f10,MODE_CHOICE(-16,-40)-(4*8)(r28)
154154+ lfd f11,MODE_CHOICE(-16,-40)-(3*8)(r28)
155155+ lfd f12,MODE_CHOICE(-16,-40)-(2*8)(r28)
156156+ nop
157157+ lfd f13,MODE_CHOICE(-16,-40)-(1*8)(r28)
158158+#else
159159+#error undefined architecture
160160+#endif
161161+162162+L2:
163163+ mr r12,r29 // Put the target address in r12 as specified.
164164+ mtctr r12 // Get the address to call into CTR.
165165+ nop
166166+ nop
167167+ bctrl // Make the call.
168168+169169+ // Deal with the return value.
170170+#if defined(__ppc64__)
171171+ mtcrf 0x3,r31 // flags in cr6 and cr7
172172+ bt 27,L(st_return_value)
173173+#elif defined(__ppc__)
174174+ mtcrf 0x1,r31 // flags in cr7
175175+#else
176176+#error undefined architecture
177177+#endif
178178+179179+ bt 30,L(done_return_value)
180180+ bt 29,L(fp_return_value)
181181+ stg r3,0(r30)
182182+#if defined(__ppc__)
183183+ bf 28,L(done_return_value) // Store the second long if necessary.
184184+ stg r4,4(r30)
185185+#endif
186186+ // Fall through
187187+188188+L(done_return_value):
189189+ lg r1,0(r1) // Restore stack pointer.
190190+ // Restore the registers we used.
191191+ lg r9,SF_RETURN(r1) // return address
192192+ lg r31,MODE_CHOICE(-4,-8)(r1)
193193+ mtlr r9
194194+ lg r30,MODE_CHOICE(-8,-16)(r1)
195195+ lg r29,MODE_CHOICE(-12,-24)(r1)
196196+ lg r28,MODE_CHOICE(-16,-32)(r1)
197197+#if defined(__ppc64__)
198198+ ld r27,-40(r1)
199199+#endif
200200+ blr
201201+202202+#if defined(__ppc64__)
203203+L(st_return_value):
204204+ // Grow the stack enough to fit the registers. Leave room for 8 args
205205+ // to trample the 1st 8 slots in param area.
206206+ stgu r1,-SF_ROUND(280)(r1) // 64 + 104 + 48 + 64
207207+208208+ // Store GPRs
209209+ std r3,SF_ARG9(r1)
210210+ std r4,SF_ARG10(r1)
211211+ std r5,SF_ARG11(r1)
212212+ std r6,SF_ARG12(r1)
213213+ nop
214214+ std r7,SF_ARG13(r1)
215215+ std r8,SF_ARG14(r1)
216216+ std r9,SF_ARG15(r1)
217217+ std r10,SF_ARG16(r1)
218218+219219+ // Store FPRs
220220+ nop
221221+ bf 26,L(call_struct_to_ram_form)
222222+ stfd f1,SF_ARG17(r1)
223223+ stfd f2,SF_ARG18(r1)
224224+ stfd f3,SF_ARG19(r1)
225225+ stfd f4,SF_ARG20(r1)
226226+ nop
227227+ stfd f5,SF_ARG21(r1)
228228+ stfd f6,SF_ARG22(r1)
229229+ stfd f7,SF_ARG23(r1)
230230+ stfd f8,SF_ARG24(r1)
231231+ nop
232232+ stfd f9,SF_ARG25(r1)
233233+ stfd f10,SF_ARG26(r1)
234234+ stfd f11,SF_ARG27(r1)
235235+ stfd f12,SF_ARG28(r1)
236236+ nop
237237+ stfd f13,SF_ARG29(r1)
238238+239239+L(call_struct_to_ram_form):
240240+ ld r3,0(r27) // extended_cif->cif*
241241+ ld r3,16(r3) // ffi_cif->rtype*
242242+ addi r4,r1,SF_ARG9 // stored GPRs
243243+ addi r6,r1,SF_ARG17 // stored FPRs
244244+ li r5,0 // GPR size ptr (NULL)
245245+ li r7,0 // FPR size ptr (NULL)
246246+ li r8,0 // FPR count ptr (NULL)
247247+ li r10,0 // struct offset (NULL)
248248+ mr r9,r30 // return area
249249+ bl Lffi64_struct_to_ram_form$stub
250250+ lg r1,0(r1) // Restore stack pointer.
251251+ b L(done_return_value)
252252+#endif
253253+254254+L(fp_return_value):
255255+ /* Do we have long double to store? */
256256+ bf 31,L(fd_return_value)
257257+ stfd f1,0(r30)
258258+ stfd f2,8(r30)
259259+ b L(done_return_value)
260260+261261+L(fd_return_value):
262262+ /* Do we have double to store? */
263263+ bf 28,L(float_return_value)
264264+ stfd f1,0(r30)
265265+ b L(done_return_value)
266266+267267+L(float_return_value):
268268+ /* We only have a float to store. */
269269+ stfs f1,0(r30)
270270+ b L(done_return_value)
271271+272272+LFE1:
273273+/* END(_ffi_call_DARWIN) */
274274+275275+/* Provide a null definition of _ffi_call_AIX. */
276276+.text
277277+ .align 2
278278+.globl _ffi_call_AIX
279279+.text
280280+ .align 2
281281+_ffi_call_AIX:
282282+ blr
283283+/* END(_ffi_call_AIX) */
284284+285285+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
286286+EH_frame1:
287287+ .set L$set$0,LECIE1-LSCIE1
288288+ .long L$set$0 ; Length of Common Information Entry
289289+LSCIE1:
290290+ .long 0x0 ; CIE Identifier Tag
291291+ .byte 0x1 ; CIE Version
292292+ .ascii "zR\0" ; CIE Augmentation
293293+ .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
294294+ .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
295295+ .byte 0x41 ; CIE RA Column
296296+ .byte 0x1 ; uleb128 0x1; Augmentation size
297297+ .byte 0x10 ; FDE Encoding (pcrel)
298298+ .byte 0xc ; DW_CFA_def_cfa
299299+ .byte 0x1 ; uleb128 0x1
300300+ .byte 0x0 ; uleb128 0x0
301301+ .align LOG2_GPR_BYTES
302302+LECIE1:
303303+.globl _ffi_call_DARWIN.eh
304304+_ffi_call_DARWIN.eh:
305305+LSFDE1:
306306+ .set L$set$1,LEFDE1-LASFDE1
307307+ .long L$set$1 ; FDE Length
308308+309309+LASFDE1:
310310+ .long LASFDE1-EH_frame1 ; FDE CIE offset
311311+ .g_long LFB0-. ; FDE initial location
312312+ .set L$set$3,LFE1-LFB0
313313+ .g_long L$set$3 ; FDE address range
314314+ .byte 0x0 ; uleb128 0x0; Augmentation size
315315+ .byte 0x4 ; DW_CFA_advance_loc4
316316+ .set L$set$4,LCFI0-LFB1
317317+ .long L$set$4
318318+ .byte 0xd ; DW_CFA_def_cfa_register
319319+ .byte 0x08 ; uleb128 0x08
320320+ .byte 0x4 ; DW_CFA_advance_loc4
321321+ .set L$set$5,LCFI1-LCFI0
322322+ .long L$set$5
323323+ .byte 0x11 ; DW_CFA_offset_extended_sf
324324+ .byte 0x41 ; uleb128 0x41
325325+ .byte 0x7e ; sleb128 -2
326326+ .byte 0x9f ; DW_CFA_offset, column 0x1f
327327+ .byte 0x1 ; uleb128 0x1
328328+ .byte 0x9e ; DW_CFA_offset, column 0x1e
329329+ .byte 0x2 ; uleb128 0x2
330330+ .byte 0x9d ; DW_CFA_offset, column 0x1d
331331+ .byte 0x3 ; uleb128 0x3
332332+ .byte 0x9c ; DW_CFA_offset, column 0x1c
333333+ .byte 0x4 ; uleb128 0x4
334334+ .byte 0x4 ; DW_CFA_advance_loc4
335335+ .set L$set$6,LCFI2-LCFI1
336336+ .long L$set$6
337337+ .byte 0xd ; DW_CFA_def_cfa_register
338338+ .byte 0x1c ; uleb128 0x1c
339339+ .align LOG2_GPR_BYTES
340340+LEFDE1:
341341+342342+#if defined(__ppc64__)
343343+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
344344+ .align LOG2_GPR_BYTES
345345+346346+Lffi64_struct_to_ram_form$stub:
347347+ .indirect_symbol _ffi64_struct_to_ram_form
348348+ mflr r0
349349+ bcl 20,31,LO$ffi64_struct_to_ram_form
350350+351351+LO$ffi64_struct_to_ram_form:
352352+ mflr r11
353353+ addis r11,r11,ha16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form)
354354+ mtlr r0
355355+ lgu r12,lo16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form)(r11)
356356+ mtctr r12
357357+ bctr
358358+359359+.lazy_symbol_pointer
360360+L_ffi64_struct_to_ram_form$lazy_ptr:
361361+ .indirect_symbol _ffi64_struct_to_ram_form
362362+ .g_long dyld_stub_binding_helper
363363+364364+#endif // __ppc64__
365365+#endif // __ppc__ || __ppc64__
+85
src/libffi/powerpc/ppc-darwin.h
···11+/* -----------------------------------------------------------------------
22+ ppc-darwin.h - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
33+ Inc.
44+55+ Permission is hereby granted, free of charge, to any person obtaining
66+ a copy of this software and associated documentation files (the
77+ ``Software''), to deal in the Software without restriction, including
88+ without limitation the rights to use, copy, modify, merge, publish,
99+ distribute, sublicense, and/or sell copies of the Software, and to
1010+ permit persons to whom the Software is furnished to do so, subject to
1111+ the following conditions:
1212+1313+ The above copyright notice and this permission notice shall be included
1414+ in all copies or substantial portions of the Software.
1515+1616+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1717+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1818+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1919+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
2020+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2121+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2222+ OTHER DEALINGS IN THE SOFTWARE.
2323+ ----------------------------------------------------------------------- */
2424+2525+#define L(x) x
2626+2727+#define SF_ARG9 MODE_CHOICE(56,112)
2828+#define SF_ARG10 MODE_CHOICE(60,120)
2929+#define SF_ARG11 MODE_CHOICE(64,128)
3030+#define SF_ARG12 MODE_CHOICE(68,136)
3131+#define SF_ARG13 MODE_CHOICE(72,144)
3232+#define SF_ARG14 MODE_CHOICE(76,152)
3333+#define SF_ARG15 MODE_CHOICE(80,160)
3434+#define SF_ARG16 MODE_CHOICE(84,168)
3535+#define SF_ARG17 MODE_CHOICE(88,176)
3636+#define SF_ARG18 MODE_CHOICE(92,184)
3737+#define SF_ARG19 MODE_CHOICE(96,192)
3838+#define SF_ARG20 MODE_CHOICE(100,200)
3939+#define SF_ARG21 MODE_CHOICE(104,208)
4040+#define SF_ARG22 MODE_CHOICE(108,216)
4141+#define SF_ARG23 MODE_CHOICE(112,224)
4242+#define SF_ARG24 MODE_CHOICE(116,232)
4343+#define SF_ARG25 MODE_CHOICE(120,240)
4444+#define SF_ARG26 MODE_CHOICE(124,248)
4545+#define SF_ARG27 MODE_CHOICE(128,256)
4646+#define SF_ARG28 MODE_CHOICE(132,264)
4747+#define SF_ARG29 MODE_CHOICE(136,272)
4848+4949+#define ASM_NEEDS_REGISTERS 4
5050+#define NUM_GPR_ARG_REGISTERS 8
5151+#define NUM_FPR_ARG_REGISTERS 13
5252+5353+#define FFI_TYPE_1_BYTE(x) ((x) == FFI_TYPE_UINT8 || (x) == FFI_TYPE_SINT8)
5454+#define FFI_TYPE_2_BYTE(x) ((x) == FFI_TYPE_UINT16 || (x) == FFI_TYPE_SINT16)
5555+#define FFI_TYPE_4_BYTE(x) \
5656+ ((x) == FFI_TYPE_UINT32 || (x) == FFI_TYPE_SINT32 ||\
5757+ (x) == FFI_TYPE_INT || (x) == FFI_TYPE_FLOAT)
5858+5959+#if !defined(LIBFFI_ASM)
6060+6161+enum {
6262+ FLAG_RETURNS_NOTHING = 1 << (31 - 30), // cr7
6363+ FLAG_RETURNS_FP = 1 << (31 - 29),
6464+ FLAG_RETURNS_64BITS = 1 << (31 - 28),
6565+ FLAG_RETURNS_128BITS = 1 << (31 - 31),
6666+6767+ FLAG_RETURNS_STRUCT = 1 << (31 - 27), // cr6
6868+ FLAG_STRUCT_CONTAINS_FP = 1 << (31 - 26),
6969+7070+ FLAG_ARG_NEEDS_COPY = 1 << (31 - 7),
7171+ FLAG_FP_ARGUMENTS = 1 << (31 - 6), // cr1.eq; specified by ABI
7272+ FLAG_4_GPR_ARGUMENTS = 1 << (31 - 5),
7373+ FLAG_RETVAL_REFERENCE = 1 << (31 - 4)
7474+};
7575+7676+#if defined(__ppc64__)
7777+void ffi64_struct_to_ram_form(const ffi_type*, const char*, unsigned int*,
7878+ const char*, unsigned int*, unsigned int*, char*, unsigned int*);
7979+void ffi64_struct_to_reg_form(const ffi_type*, const char*, unsigned int*,
8080+ unsigned int*, char*, unsigned int*, char*, unsigned int*);
8181+bool ffi64_stret_needs_ptr(const ffi_type* inType,
8282+ unsigned short*, unsigned short*);
8383+#endif
8484+8585+#endif // !defined(LIBFFI_ASM)
+308
src/libffi/powerpc/ppc-darwin_closure.S
···11+#if defined(__ppc__)
22+33+/* -----------------------------------------------------------------------
44+ ppc-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
55+ Inc. based on ppc_closure.S
66+77+ PowerPC Assembly glue.
88+99+ Permission is hereby granted, free of charge, to any person obtaining
1010+ a copy of this software and associated documentation files (the
1111+ ``Software''), to deal in the Software without restriction, including
1212+ without limitation the rights to use, copy, modify, merge, publish,
1313+ distribute, sublicense, and/or sell copies of the Software, and to
1414+ permit persons to whom the Software is furnished to do so, subject to
1515+ the following conditions:
1616+1717+ The above copyright notice and this permission notice shall be included
1818+ in all copies or substantial portions of the Software.
1919+2020+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
2121+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2222+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2323+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
2424+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2525+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2626+ OTHER DEALINGS IN THE SOFTWARE.
2727+ ----------------------------------------------------------------------- */
2828+2929+#define LIBFFI_ASM
3030+3131+#include <ffi.h>
3232+#include <ppc-ffitarget.h> // for FFI_TRAMPOLINE_SIZE
3333+#include <ppc-darwin.h>
3434+#include <architecture/ppc/mode_independent_asm.h>
3535+3636+ .file "ppc-darwin_closure.S"
3737+.text
3838+ .align LOG2_GPR_BYTES
3939+ .globl _ffi_closure_ASM
4040+4141+.text
4242+ .align LOG2_GPR_BYTES
4343+4444+_ffi_closure_ASM:
4545+LFB1:
4646+ mflr r0 // Save return address
4747+ stg r0,SF_RETURN(r1)
4848+4949+LCFI0:
5050+ /* 24/48 bytes (Linkage Area)
5151+ 32/64 bytes (outgoing parameter area, always reserved)
5252+ 104 bytes (13*8 from FPR)
5353+ 16/32 bytes (result)
5454+ 176/232 total bytes */
5555+5656+ /* skip over caller save area and keep stack aligned to 16/32. */
5757+ stgu r1,-SF_ROUND(176)(r1)
5858+5959+LCFI1:
6060+ /* We want to build up an area for the parameters passed
6161+ in registers. (both floating point and integer) */
6262+6363+ /* 176/256 bytes (callee stack frame aligned to 16/32)
6464+ 24/48 bytes (caller linkage area)
6565+ 200/304 (start of caller parameter area aligned to 4/8)
6666+ */
6767+6868+ /* Save GPRs 3 - 10 (aligned to 4/8)
6969+ in the parents outgoing area. */
7070+ stg r3,200(r1)
7171+ stg r4,204(r1)
7272+ stg r5,208(r1)
7373+ stg r6,212(r1)
7474+ stg r7,216(r1)
7575+ stg r8,220(r1)
7676+ stg r9,224(r1)
7777+ stg r10,228(r1)
7878+7979+ /* Save FPRs 1 - 13. (aligned to 8) */
8080+ stfd f1,56(r1)
8181+ stfd f2,64(r1)
8282+ stfd f3,72(r1)
8383+ stfd f4,80(r1)
8484+ stfd f5,88(r1)
8585+ stfd f6,96(r1)
8686+ stfd f7,104(r1)
8787+ stfd f8,112(r1)
8888+ stfd f9,120(r1)
8989+ stfd f10,128(r1)
9090+ stfd f11,136(r1)
9191+ stfd f12,144(r1)
9292+ stfd f13,152(r1)
9393+9494+ // Set up registers for the routine that actually does the work.
9595+ mr r3,r11 // context pointer from the trampoline
9696+ addi r4,r1,160 // result storage
9797+ addi r5,r1,200 // saved GPRs
9898+ addi r6,r1,56 // saved FPRs
9999+ bl Lffi_closure_helper_DARWIN$stub
100100+101101+ /* Now r3 contains the return type. Use it to look up in a table
102102+ so we know how to deal with each type. */
103103+ addi r5,r1,160 // Copy result storage pointer.
104104+ bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR.
105105+ mflr r4 // Move to r4.
106106+ slwi r3,r3,4 // Multiply return type by 16.
107107+ add r3,r3,r4 // Add contents of table to table address.
108108+ mtctr r3
109109+ bctr
110110+111111+LFE1:
112112+/* Each of the ret_typeX code fragments has to be exactly 16 bytes long
113113+ (4 instructions). For cache effectiveness we align to a 16 byte boundary
114114+ first. */
115115+ .align 4
116116+ nop
117117+ nop
118118+ nop
119119+120120+Lget_ret_type0_addr:
121121+ blrl
122122+123123+/* case FFI_TYPE_VOID */
124124+Lret_type0:
125125+ b Lfinish
126126+ nop
127127+ nop
128128+ nop
129129+130130+/* case FFI_TYPE_INT */
131131+Lret_type1:
132132+ lwz r3,0(r5)
133133+ b Lfinish
134134+ nop
135135+ nop
136136+137137+/* case FFI_TYPE_FLOAT */
138138+Lret_type2:
139139+ lfs f1,0(r5)
140140+ b Lfinish
141141+ nop
142142+ nop
143143+144144+/* case FFI_TYPE_DOUBLE */
145145+Lret_type3:
146146+ lfd f1,0(r5)
147147+ b Lfinish
148148+ nop
149149+ nop
150150+151151+/* case FFI_TYPE_LONGDOUBLE */
152152+Lret_type4:
153153+ lfd f1,0(r5)
154154+ lfd f2,8(r5)
155155+ b Lfinish
156156+ nop
157157+158158+/* case FFI_TYPE_UINT8 */
159159+Lret_type5:
160160+ lbz r3,3(r5)
161161+ b Lfinish
162162+ nop
163163+ nop
164164+165165+/* case FFI_TYPE_SINT8 */
166166+Lret_type6:
167167+ lbz r3,3(r5)
168168+ extsb r3,r3
169169+ b Lfinish
170170+ nop
171171+172172+/* case FFI_TYPE_UINT16 */
173173+Lret_type7:
174174+ lhz r3,2(r5)
175175+ b Lfinish
176176+ nop
177177+ nop
178178+179179+/* case FFI_TYPE_SINT16 */
180180+Lret_type8:
181181+ lha r3,2(r5)
182182+ b Lfinish
183183+ nop
184184+ nop
185185+186186+/* case FFI_TYPE_UINT32 */
187187+Lret_type9: // same as Lret_type1
188188+ lwz r3,0(r5)
189189+ b Lfinish
190190+ nop
191191+ nop
192192+193193+/* case FFI_TYPE_SINT32 */
194194+Lret_type10: // same as Lret_type1
195195+ lwz r3,0(r5)
196196+ b Lfinish
197197+ nop
198198+ nop
199199+200200+/* case FFI_TYPE_UINT64 */
201201+Lret_type11:
202202+ lwz r3,0(r5)
203203+ lwz r4,4(r5)
204204+ b Lfinish
205205+ nop
206206+207207+/* case FFI_TYPE_SINT64 */
208208+Lret_type12: // same as Lret_type11
209209+ lwz r3,0(r5)
210210+ lwz r4,4(r5)
211211+ b Lfinish
212212+ nop
213213+214214+/* case FFI_TYPE_STRUCT */
215215+Lret_type13:
216216+ b Lfinish
217217+ nop
218218+ nop
219219+ nop
220220+221221+/* End 16-byte aligned cases */
222222+/* case FFI_TYPE_POINTER */
223223+// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types
224224+// are added in future, the following code will need to be updated and
225225+// padded to 16 bytes.
226226+Lret_type14:
227227+ lg r3,0(r5)
228228+ // fall through
229229+230230+/* case done */
231231+Lfinish:
232232+ addi r1,r1,SF_ROUND(176) // Restore stack pointer.
233233+ lg r0,SF_RETURN(r1) // Restore return address.
234234+ mtlr r0 // Restore link register.
235235+ blr
236236+237237+/* END(ffi_closure_ASM) */
238238+239239+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
240240+EH_frame1:
241241+ .set L$set$0,LECIE1-LSCIE1
242242+ .long L$set$0 ; Length of Common Information Entry
243243+LSCIE1:
244244+ .long 0x0 ; CIE Identifier Tag
245245+ .byte 0x1 ; CIE Version
246246+ .ascii "zR\0" ; CIE Augmentation
247247+ .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
248248+ .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
249249+ .byte 0x41 ; CIE RA Column
250250+ .byte 0x1 ; uleb128 0x1; Augmentation size
251251+ .byte 0x10 ; FDE Encoding (pcrel)
252252+ .byte 0xc ; DW_CFA_def_cfa
253253+ .byte 0x1 ; uleb128 0x1
254254+ .byte 0x0 ; uleb128 0x0
255255+ .align LOG2_GPR_BYTES
256256+LECIE1:
257257+.globl _ffi_closure_ASM.eh
258258+_ffi_closure_ASM.eh:
259259+LSFDE1:
260260+ .set L$set$1,LEFDE1-LASFDE1
261261+ .long L$set$1 ; FDE Length
262262+263263+LASFDE1:
264264+ .long LASFDE1-EH_frame1 ; FDE CIE offset
265265+ .g_long LFB1-. ; FDE initial location
266266+ .set L$set$3,LFE1-LFB1
267267+ .g_long L$set$3 ; FDE address range
268268+ .byte 0x0 ; uleb128 0x0; Augmentation size
269269+ .byte 0x4 ; DW_CFA_advance_loc4
270270+ .set L$set$3,LCFI1-LCFI0
271271+ .long L$set$3
272272+ .byte 0xe ; DW_CFA_def_cfa_offset
273273+ .byte 176,1 ; uleb128 176
274274+ .byte 0x4 ; DW_CFA_advance_loc4
275275+ .set L$set$4,LCFI0-LFB1
276276+ .long L$set$4
277277+ .byte 0x11 ; DW_CFA_offset_extended_sf
278278+ .byte 0x41 ; uleb128 0x41
279279+ .byte 0x7e ; sleb128 -2
280280+ .align LOG2_GPR_BYTES
281281+282282+LEFDE1:
283283+.data
284284+ .align LOG2_GPR_BYTES
285285+LDFCM0:
286286+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
287287+ .align LOG2_GPR_BYTES
288288+289289+Lffi_closure_helper_DARWIN$stub:
290290+ .indirect_symbol _ffi_closure_helper_DARWIN
291291+ mflr r0
292292+ bcl 20,31,LO$ffi_closure_helper_DARWIN
293293+294294+LO$ffi_closure_helper_DARWIN:
295295+ mflr r11
296296+ addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)
297297+ mtlr r0
298298+ lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11)
299299+ mtctr r12
300300+ bctr
301301+302302+.lazy_symbol_pointer
303303+L_ffi_closure_helper_DARWIN$lazy_ptr:
304304+ .indirect_symbol _ffi_closure_helper_DARWIN
305305+ .g_long dyld_stub_binding_helper
306306+307307+308308+#endif // __ppc__
+1767
src/libffi/powerpc/ppc-ffi_darwin.c
···11+#if defined(__ppc__) || defined(__ppc64__)
22+33+/* -----------------------------------------------------------------------
44+ ffi.c - Copyright (c) 1998 Geoffrey Keating
55+66+ PowerPC Foreign Function Interface
77+88+ Darwin ABI support (c) 2001 John Hornkvist
99+ AIX ABI support (c) 2002 Free Software Foundation, Inc.
1010+1111+ Permission is hereby granted, free of charge, to any person obtaining
1212+ a copy of this software and associated documentation files (the
1313+ ``Software''), to deal in the Software without restriction, including
1414+ without limitation the rights to use, copy, modify, merge, publish,
1515+ distribute, sublicense, and/or sell copies of the Software, and to
1616+ permit persons to whom the Software is furnished to do so, subject to
1717+ the following conditions:
1818+1919+ The above copyright notice and this permission notice shall be included
2020+ in all copies or substantial portions of the Software.
2121+2222+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
2323+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2424+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2525+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
2626+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2727+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2828+ OTHER DEALINGS IN THE SOFTWARE.
2929+ ----------------------------------------------------------------------- */
3030+3131+#include <ffi.h>
3232+#include <ffi_common.h>
3333+3434+#include <stdbool.h>
3535+#include <stdio.h>
3636+#include <stdlib.h>
3737+#include <ppc-darwin.h>
3838+#include <architecture/ppc/mode_independent_asm.h>
3939+4040+#if defined(POWERPC_DARWIN)
4141+#include <libkern/OSCacheControl.h> // for sys_icache_invalidate()
4242+#endif
4343+4444+extern void ffi_closure_ASM(void);
4545+4646+// The layout of a function descriptor. A C function pointer really
4747+// points to one of these.
4848+typedef struct aix_fd_struct {
4949+ void* code_pointer;
5050+ void* toc;
5151+} aix_fd;
5252+5353+/* ffi_prep_args is called by the assembly routine once stack space
5454+ has been allocated for the function's arguments.
5555+5656+ The stack layout we want looks like this:
5757+5858+ | Return address from ffi_call_DARWIN | higher addresses
5959+ |--------------------------------------------|
6060+ | Previous backchain pointer 4/8 | stack pointer here
6161+ |--------------------------------------------|-\ <<< on entry to
6262+ | Saved r28-r31 (4/8)*4 | | ffi_call_DARWIN
6363+ |--------------------------------------------| |
6464+ | Parameters (at least 8*(4/8)=32/64) | | (176) +112 - +288
6565+ |--------------------------------------------| |
6666+ | Space for GPR2 4/8 | |
6767+ |--------------------------------------------| | stack |
6868+ | Reserved (4/8)*2 | | grows |
6969+ |--------------------------------------------| | down V
7070+ | Space for callee's LR 4/8 | |
7171+ |--------------------------------------------| | lower addresses
7272+ | Saved CR 4/8 | |
7373+ |--------------------------------------------| | stack pointer here
7474+ | Current backchain pointer 4/8 | | during
7575+ |--------------------------------------------|-/ <<< ffi_call_DARWIN
7676+7777+ Note: ppc64 CR is saved in the low word of a long on the stack.
7878+*/
7979+8080+/*@-exportheader@*/
8181+void
8282+ffi_prep_args(
8383+ extended_cif* inEcif,
8484+ unsigned *const stack)
8585+/*@=exportheader@*/
8686+{
8787+ /* Copy the ecif to a local var so we can trample the arg.
8888+ BC note: test this with GP later for possible problems... */
8989+ volatile extended_cif* ecif = inEcif;
9090+9191+ const unsigned bytes = ecif->cif->bytes;
9292+ const unsigned flags = ecif->cif->flags;
9393+9494+ /* Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode
9595+ and 8 in 64-bit mode. */
9696+ unsigned long *const longStack = (unsigned long *const)stack;
9797+9898+ /* 'stacktop' points at the previous backchain pointer. */
9999+#if defined(__ppc64__)
100100+ // In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area,
101101+ // saved registers, and an extra FPR.
102102+ unsigned long *const stacktop =
103103+ (unsigned long *)(unsigned long)((char*)longStack + bytes + 96);
104104+#elif defined(__ppc__)
105105+ unsigned long *const stacktop = longStack + (bytes / sizeof(long));
106106+#else
107107+#error undefined architecture
108108+#endif
109109+110110+ /* 'fpr_base' points at the space for fpr1, and grows upwards as
111111+ we use FPR registers. */
112112+ double* fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) -
113113+ NUM_FPR_ARG_REGISTERS;
114114+115115+#if defined(__ppc64__)
116116+ // 64-bit saves an extra register, and uses an extra FPR. Knock fpr_base
117117+ // down a couple pegs.
118118+ fpr_base -= 2;
119119+#endif
120120+121121+ unsigned int fparg_count = 0;
122122+123123+ /* 'next_arg' grows up as we put parameters in it. */
124124+ unsigned long* next_arg = longStack + 6; /* 6 reserved positions. */
125125+126126+ int i;
127127+ double double_tmp;
128128+ void** p_argv = ecif->avalue;
129129+ unsigned long gprvalue;
130130+ ffi_type** ptr = ecif->cif->arg_types;
131131+132132+ /* Check that everything starts aligned properly. */
133133+ FFI_ASSERT(stack == SF_ROUND(stack));
134134+ FFI_ASSERT(stacktop == SF_ROUND(stacktop));
135135+ FFI_ASSERT(bytes == SF_ROUND(bytes));
136136+137137+ /* Deal with return values that are actually pass-by-reference.
138138+ Rule:
139139+ Return values are referenced by r3, so r4 is the first parameter. */
140140+141141+ if (flags & FLAG_RETVAL_REFERENCE)
142142+ *next_arg++ = (unsigned long)(char*)ecif->rvalue;
143143+144144+ /* Now for the arguments. */
145145+ for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++)
146146+ {
147147+ switch ((*ptr)->type)
148148+ {
149149+ /* If a floating-point parameter appears before all of the general-
150150+ purpose registers are filled, the corresponding GPRs that match
151151+ the size of the floating-point parameter are shadowed for the
152152+ benefit of vararg and pre-ANSI functions. */
153153+ case FFI_TYPE_FLOAT:
154154+ double_tmp = *(float*)*p_argv;
155155+156156+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
157157+ *fpr_base++ = double_tmp;
158158+159159+ *(double*)next_arg = double_tmp;
160160+161161+ next_arg++;
162162+ fparg_count++;
163163+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
164164+165165+ break;
166166+167167+ case FFI_TYPE_DOUBLE:
168168+ double_tmp = *(double*)*p_argv;
169169+170170+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
171171+ *fpr_base++ = double_tmp;
172172+173173+ *(double*)next_arg = double_tmp;
174174+175175+ next_arg += MODE_CHOICE(2,1);
176176+ fparg_count++;
177177+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
178178+179179+ break;
180180+181181+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
182182+ case FFI_TYPE_LONGDOUBLE:
183183+#if defined(__ppc64__)
184184+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
185185+ *(long double*)fpr_base = *(long double*)*p_argv;
186186+#elif defined(__ppc__)
187187+ if (fparg_count < NUM_FPR_ARG_REGISTERS - 1)
188188+ *(long double*)fpr_base = *(long double*)*p_argv;
189189+ else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1)
190190+ *(double*)fpr_base = *(double*)*p_argv;
191191+#else
192192+#error undefined architecture
193193+#endif
194194+195195+ *(long double*)next_arg = *(long double*)*p_argv;
196196+ fparg_count += 2;
197197+ fpr_base += 2;
198198+ next_arg += MODE_CHOICE(4,2);
199199+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
200200+201201+ break;
202202+#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
203203+204204+ case FFI_TYPE_UINT64:
205205+ case FFI_TYPE_SINT64:
206206+#if defined(__ppc64__)
207207+ gprvalue = *(long long*)*p_argv;
208208+ goto putgpr;
209209+#elif defined(__ppc__)
210210+ *(long long*)next_arg = *(long long*)*p_argv;
211211+ next_arg += 2;
212212+ break;
213213+#else
214214+#error undefined architecture
215215+#endif
216216+217217+ case FFI_TYPE_POINTER:
218218+ gprvalue = *(unsigned long*)*p_argv;
219219+ goto putgpr;
220220+221221+ case FFI_TYPE_UINT8:
222222+ gprvalue = *(unsigned char*)*p_argv;
223223+ goto putgpr;
224224+225225+ case FFI_TYPE_SINT8:
226226+ gprvalue = *(signed char*)*p_argv;
227227+ goto putgpr;
228228+229229+ case FFI_TYPE_UINT16:
230230+ gprvalue = *(unsigned short*)*p_argv;
231231+ goto putgpr;
232232+233233+ case FFI_TYPE_SINT16:
234234+ gprvalue = *(signed short*)*p_argv;
235235+ goto putgpr;
236236+237237+ case FFI_TYPE_STRUCT:
238238+ {
239239+#if defined(__ppc64__)
240240+ unsigned int gprSize = 0;
241241+ unsigned int fprSize = 0;
242242+243243+ ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count,
244244+ (char*)next_arg, &gprSize, (char*)fpr_base, &fprSize);
245245+ next_arg += gprSize / sizeof(long);
246246+ fpr_base += fprSize / sizeof(double);
247247+248248+#elif defined(__ppc__)
249249+ char* dest_cpy = (char*)next_arg;
250250+251251+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
252252+ SI 4 bytes) are aligned as if they were those modes.
253253+ Structures with 3 byte in size are padded upwards. */
254254+ unsigned size_al = (*ptr)->size;
255255+256256+ /* If the first member of the struct is a double, then align
257257+ the struct to double-word. */
258258+ if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
259259+ size_al = ALIGN((*ptr)->size, 8);
260260+261261+ if (ecif->cif->abi == FFI_DARWIN)
262262+ {
263263+ if (size_al < 3)
264264+ dest_cpy += 4 - size_al;
265265+ }
266266+267267+ memcpy((char*)dest_cpy, (char*)*p_argv, size_al);
268268+ next_arg += (size_al + 3) / 4;
269269+#else
270270+#error undefined architecture
271271+#endif
272272+ break;
273273+ }
274274+275275+ case FFI_TYPE_INT:
276276+ case FFI_TYPE_UINT32:
277277+ case FFI_TYPE_SINT32:
278278+ gprvalue = *(unsigned*)*p_argv;
279279+280280+putgpr:
281281+ *next_arg++ = gprvalue;
282282+ break;
283283+284284+ default:
285285+ break;
286286+ }
287287+ }
288288+289289+ /* Check that we didn't overrun the stack... */
290290+ //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
291291+ //FFI_ASSERT((unsigned *)fpr_base
292292+ // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
293293+ //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
294294+}
295295+296296+#if defined(__ppc64__)
297297+298298+bool
299299+ffi64_struct_contains_fp(
300300+ const ffi_type* inType)
301301+{
302302+ bool containsFP = false;
303303+ unsigned int i;
304304+305305+ for (i = 0; inType->elements[i] != NULL && !containsFP; i++)
306306+ {
307307+ if (inType->elements[i]->type == FFI_TYPE_FLOAT ||
308308+ inType->elements[i]->type == FFI_TYPE_DOUBLE ||
309309+ inType->elements[i]->type == FFI_TYPE_LONGDOUBLE)
310310+ containsFP = true;
311311+ else if (inType->elements[i]->type == FFI_TYPE_STRUCT)
312312+ containsFP = ffi64_struct_contains_fp(inType->elements[i]);
313313+ }
314314+315315+ return containsFP;
316316+}
317317+318318+#endif // defined(__ppc64__)
319319+320320+/* Perform machine dependent cif processing. */
321321+ffi_status
322322+ffi_prep_cif_machdep(
323323+ ffi_cif* cif)
324324+{
325325+ /* All this is for the DARWIN ABI. */
326326+ int i;
327327+ ffi_type** ptr;
328328+ int intarg_count = 0;
329329+ int fparg_count = 0;
330330+ unsigned int flags = 0;
331331+ unsigned int size_al = 0;
332332+333333+ /* All the machine-independent calculation of cif->bytes will be wrong.
334334+ Redo the calculation for DARWIN. */
335335+336336+ /* Space for the frame pointer, callee's LR, CR, etc, and for
337337+ the asm's temp regs. */
338338+ unsigned int bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
339339+340340+ /* Return value handling. The rules are as follows:
341341+ - 32-bit (or less) integer values are returned in gpr3;
342342+ - Structures of size <= 4 bytes also returned in gpr3;
343343+ - 64-bit integer values and structures between 5 and 8 bytes are
344344+ returned in gpr3 and gpr4;
345345+ - Single/double FP values are returned in fpr1;
346346+ - Long double FP (if not equivalent to double) values are returned in
347347+ fpr1 and fpr2;
348348+ - Larger structures values are allocated space and a pointer is passed
349349+ as the first argument. */
350350+ switch (cif->rtype->type)
351351+ {
352352+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
353353+ case FFI_TYPE_LONGDOUBLE:
354354+ flags |= FLAG_RETURNS_128BITS;
355355+ flags |= FLAG_RETURNS_FP;
356356+ break;
357357+#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
358358+359359+ case FFI_TYPE_DOUBLE:
360360+ flags |= FLAG_RETURNS_64BITS;
361361+ /* Fall through. */
362362+ case FFI_TYPE_FLOAT:
363363+ flags |= FLAG_RETURNS_FP;
364364+ break;
365365+366366+#if defined(__ppc64__)
367367+ case FFI_TYPE_POINTER:
368368+#endif
369369+ case FFI_TYPE_UINT64:
370370+ case FFI_TYPE_SINT64:
371371+ flags |= FLAG_RETURNS_64BITS;
372372+ break;
373373+374374+ case FFI_TYPE_STRUCT:
375375+ {
376376+#if defined(__ppc64__)
377377+378378+ if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
379379+ {
380380+ flags |= FLAG_RETVAL_REFERENCE;
381381+ flags |= FLAG_RETURNS_NOTHING;
382382+ intarg_count++;
383383+ }
384384+ else
385385+ {
386386+ flags |= FLAG_RETURNS_STRUCT;
387387+388388+ if (ffi64_struct_contains_fp(cif->rtype))
389389+ flags |= FLAG_STRUCT_CONTAINS_FP;
390390+ }
391391+392392+#elif defined(__ppc__)
393393+394394+ flags |= FLAG_RETVAL_REFERENCE;
395395+ flags |= FLAG_RETURNS_NOTHING;
396396+ intarg_count++;
397397+398398+#else
399399+#error undefined architecture
400400+#endif
401401+ break;
402402+ }
403403+404404+ case FFI_TYPE_VOID:
405405+ flags |= FLAG_RETURNS_NOTHING;
406406+ break;
407407+408408+ default:
409409+ /* Returns 32-bit integer, or similar. Nothing to do here. */
410410+ break;
411411+ }
412412+413413+ /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
414414+ first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
415415+ goes on the stack. Structures are passed as a pointer to a copy of
416416+ the structure. Stuff on the stack needs to keep proper alignment. */
417417+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
418418+ {
419419+ switch ((*ptr)->type)
420420+ {
421421+ case FFI_TYPE_FLOAT:
422422+ case FFI_TYPE_DOUBLE:
423423+ fparg_count++;
424424+ /* If this FP arg is going on the stack, it must be
425425+ 8-byte-aligned. */
426426+ if (fparg_count > NUM_FPR_ARG_REGISTERS
427427+ && intarg_count % 2 != 0)
428428+ intarg_count++;
429429+ break;
430430+431431+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
432432+ case FFI_TYPE_LONGDOUBLE:
433433+ fparg_count += 2;
434434+ /* If this FP arg is going on the stack, it must be
435435+ 8-byte-aligned. */
436436+437437+ if (
438438+#if defined(__ppc64__)
439439+ fparg_count > NUM_FPR_ARG_REGISTERS + 1
440440+#elif defined(__ppc__)
441441+ fparg_count > NUM_FPR_ARG_REGISTERS
442442+#else
443443+#error undefined architecture
444444+#endif
445445+ && intarg_count % 2 != 0)
446446+ intarg_count++;
447447+448448+ intarg_count += 2;
449449+ break;
450450+#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
451451+452452+ case FFI_TYPE_UINT64:
453453+ case FFI_TYPE_SINT64:
454454+ /* 'long long' arguments are passed as two words, but
455455+ either both words must fit in registers or both go
456456+ on the stack. If they go on the stack, they must
457457+ be 8-byte-aligned. */
458458+ if (intarg_count == NUM_GPR_ARG_REGISTERS - 1
459459+ || (intarg_count >= NUM_GPR_ARG_REGISTERS
460460+ && intarg_count % 2 != 0))
461461+ intarg_count++;
462462+463463+ intarg_count += MODE_CHOICE(2,1);
464464+465465+ break;
466466+467467+ case FFI_TYPE_STRUCT:
468468+ size_al = (*ptr)->size;
469469+ /* If the first member of the struct is a double, then align
470470+ the struct to double-word. */
471471+ if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
472472+ size_al = ALIGN((*ptr)->size, 8);
473473+474474+#if defined(__ppc64__)
475475+ // Look for FP struct members.
476476+ unsigned int j;
477477+478478+ for (j = 0; (*ptr)->elements[j] != NULL; j++)
479479+ {
480480+ if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT ||
481481+ (*ptr)->elements[j]->type == FFI_TYPE_DOUBLE)
482482+ {
483483+ fparg_count++;
484484+485485+ if (fparg_count > NUM_FPR_ARG_REGISTERS)
486486+ intarg_count++;
487487+ }
488488+ else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE)
489489+ {
490490+ fparg_count += 2;
491491+492492+ if (fparg_count > NUM_FPR_ARG_REGISTERS + 1)
493493+ intarg_count += 2;
494494+ }
495495+ else
496496+ intarg_count++;
497497+ }
498498+#elif defined(__ppc__)
499499+ intarg_count += (size_al + 3) / 4;
500500+#else
501501+#error undefined architecture
502502+#endif
503503+504504+ break;
505505+506506+ default:
507507+ /* Everything else is passed as a 4/8-byte word in a GPR, either
508508+ the object itself or a pointer to it. */
509509+ intarg_count++;
510510+ break;
511511+ }
512512+ }
513513+514514+ /* Space for the FPR registers, if needed. */
515515+ if (fparg_count != 0)
516516+ {
517517+ flags |= FLAG_FP_ARGUMENTS;
518518+#if defined(__ppc64__)
519519+ bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double);
520520+#elif defined(__ppc__)
521521+ bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
522522+#else
523523+#error undefined architecture
524524+#endif
525525+ }
526526+527527+ /* Stack space. */
528528+#if defined(__ppc64__)
529529+ if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
530530+ bytes += (intarg_count + fparg_count) * sizeof(long);
531531+#elif defined(__ppc__)
532532+ if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
533533+ bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
534534+#else
535535+#error undefined architecture
536536+#endif
537537+ else
538538+ bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
539539+540540+ /* The stack space allocated needs to be a multiple of 16/32 bytes. */
541541+ bytes = SF_ROUND(bytes);
542542+543543+ cif->flags = flags;
544544+ cif->bytes = bytes;
545545+546546+ return FFI_OK;
547547+}
548548+549549+/*@-declundef@*/
550550+/*@-exportheader@*/
551551+extern void
552552+ffi_call_AIX(
553553+/*@out@*/ extended_cif*,
554554+ unsigned,
555555+ unsigned,
556556+/*@out@*/ unsigned*,
557557+ void (*fn)(void),
558558+ void (*fn2)(extended_cif*, unsigned *const));
559559+560560+extern void
561561+ffi_call_DARWIN(
562562+/*@out@*/ extended_cif*,
563563+ unsigned long,
564564+ unsigned,
565565+/*@out@*/ unsigned*,
566566+ void (*fn)(void),
567567+ void (*fn2)(extended_cif*, unsigned *const));
568568+/*@=declundef@*/
569569+/*@=exportheader@*/
570570+571571+void
572572+ffi_call(
573573+/*@dependent@*/ ffi_cif* cif,
574574+ void (*fn)(void),
575575+/*@out@*/ void* rvalue,
576576+/*@dependent@*/ void** avalue)
577577+{
578578+ extended_cif ecif;
579579+580580+ ecif.cif = cif;
581581+ ecif.avalue = avalue;
582582+583583+ /* If the return value is a struct and we don't have a return
584584+ value address then we need to make one. */
585585+ if ((rvalue == NULL) &&
586586+ (cif->rtype->type == FFI_TYPE_STRUCT))
587587+ {
588588+ /*@-sysunrecog@*/
589589+ ecif.rvalue = alloca(cif->rtype->size);
590590+ /*@=sysunrecog@*/
591591+ }
592592+ else
593593+ ecif.rvalue = rvalue;
594594+595595+ switch (cif->abi)
596596+ {
597597+ case FFI_AIX:
598598+ /*@-usedef@*/
599599+ ffi_call_AIX(&ecif, -cif->bytes,
600600+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
601601+ /*@=usedef@*/
602602+ break;
603603+604604+ case FFI_DARWIN:
605605+ /*@-usedef@*/
606606+ ffi_call_DARWIN(&ecif, -(long)cif->bytes,
607607+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
608608+ /*@=usedef@*/
609609+ break;
610610+611611+ default:
612612+ FFI_ASSERT(0);
613613+ break;
614614+ }
615615+}
616616+617617+/* here I'd like to add the stack frame layout we use in darwin_closure.S
618618+ and aix_clsoure.S
619619+620620+ SP previous -> +---------------------------------------+ <--- child frame
621621+ | back chain to caller 4 |
622622+ +---------------------------------------+ 4
623623+ | saved CR 4 |
624624+ +---------------------------------------+ 8
625625+ | saved LR 4 |
626626+ +---------------------------------------+ 12
627627+ | reserved for compilers 4 |
628628+ +---------------------------------------+ 16
629629+ | reserved for binders 4 |
630630+ +---------------------------------------+ 20
631631+ | saved TOC pointer 4 |
632632+ +---------------------------------------+ 24
633633+ | always reserved 8*4=32 (previous GPRs)|
634634+ | according to the linkage convention |
635635+ | from AIX |
636636+ +---------------------------------------+ 56
637637+ | our FPR area 13*8=104 |
638638+ | f1 |
639639+ | . |
640640+ | f13 |
641641+ +---------------------------------------+ 160
642642+ | result area 8 |
643643+ +---------------------------------------+ 168
644644+ | alignement to the next multiple of 16 |
645645+SP current --> +---------------------------------------+ 176 <- parent frame
646646+ | back chain to caller 4 |
647647+ +---------------------------------------+ 180
648648+ | saved CR 4 |
649649+ +---------------------------------------+ 184
650650+ | saved LR 4 |
651651+ +---------------------------------------+ 188
652652+ | reserved for compilers 4 |
653653+ +---------------------------------------+ 192
654654+ | reserved for binders 4 |
655655+ +---------------------------------------+ 196
656656+ | saved TOC pointer 4 |
657657+ +---------------------------------------+ 200
658658+ | always reserved 8*4=32 we store our |
659659+ | GPRs here |
660660+ | r3 |
661661+ | . |
662662+ | r10 |
663663+ +---------------------------------------+ 232
664664+ | overflow part |
665665+ +---------------------------------------+ xxx
666666+ | ???? |
667667+ +---------------------------------------+ xxx
668668+*/
669669+670670+#if !defined(POWERPC_DARWIN)
671671+672672+#define MIN_LINE_SIZE 32
673673+674674+static void
675675+flush_icache(
676676+ char* addr)
677677+{
678678+#ifndef _AIX
679679+ __asm__ volatile (
680680+ "dcbf 0,%0\n"
681681+ "sync\n"
682682+ "icbi 0,%0\n"
683683+ "sync\n"
684684+ "isync"
685685+ : : "r" (addr) : "memory");
686686+#endif
687687+}
688688+689689+static void
690690+flush_range(
691691+ char* addr,
692692+ int size)
693693+{
694694+ int i;
695695+696696+ for (i = 0; i < size; i += MIN_LINE_SIZE)
697697+ flush_icache(addr + i);
698698+699699+ flush_icache(addr + size - 1);
700700+}
701701+702702+#endif // !defined(POWERPC_DARWIN)
703703+704704+ffi_status
705705+ffi_prep_closure(
706706+ ffi_closure* closure,
707707+ ffi_cif* cif,
708708+ void (*fun)(ffi_cif*, void*, void**, void*),
709709+ void* user_data)
710710+{
711711+ switch (cif->abi)
712712+ {
713713+ case FFI_DARWIN:
714714+ {
715715+ FFI_ASSERT (cif->abi == FFI_DARWIN);
716716+717717+ unsigned int* tramp = (unsigned int*)&closure->tramp[0];
718718+719719+#if defined(__ppc64__)
720720+ tramp[0] = 0x7c0802a6; // mflr r0
721721+ tramp[1] = 0x429f0005; // bcl 20,31,+0x8
722722+ tramp[2] = 0x7d6802a6; // mflr r11
723723+ tramp[3] = 0x7c0803a6; // mtlr r0
724724+ tramp[4] = 0xe98b0018; // ld r12,24(r11)
725725+ tramp[5] = 0x7d8903a6; // mtctr r12
726726+ tramp[6] = 0xe96b0020; // ld r11,32(r11)
727727+ tramp[7] = 0x4e800420; // bctr
728728+ *(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM;
729729+ *(unsigned long*)&tramp[10] = (unsigned long)closure;
730730+#elif defined(__ppc__)
731731+ tramp[0] = 0x7c0802a6; // mflr r0
732732+ tramp[1] = 0x429f0005; // bcl 20,31,+0x8
733733+ tramp[2] = 0x7d6802a6; // mflr r11
734734+ tramp[3] = 0x7c0803a6; // mtlr r0
735735+ tramp[4] = 0x818b0018; // lwz r12,24(r11)
736736+ tramp[5] = 0x7d8903a6; // mtctr r12
737737+ tramp[6] = 0x816b001c; // lwz r11,28(r11)
738738+ tramp[7] = 0x4e800420; // bctr
739739+ tramp[8] = (unsigned long)ffi_closure_ASM;
740740+ tramp[9] = (unsigned long)closure;
741741+#else
742742+#error undefined architecture
743743+#endif
744744+745745+ closure->cif = cif;
746746+ closure->fun = fun;
747747+ closure->user_data = user_data;
748748+749749+ // Flush the icache. Only necessary on Darwin.
750750+#if defined(POWERPC_DARWIN)
751751+ sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE);
752752+#else
753753+ flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE);
754754+#endif
755755+756756+ break;
757757+ }
758758+759759+ case FFI_AIX:
760760+ {
761761+ FFI_ASSERT (cif->abi == FFI_AIX);
762762+763763+ ffi_aix_trampoline_struct* tramp_aix =
764764+ (ffi_aix_trampoline_struct*)(closure->tramp);
765765+ aix_fd* fd = (aix_fd*)(void*)ffi_closure_ASM;
766766+767767+ tramp_aix->code_pointer = fd->code_pointer;
768768+ tramp_aix->toc = fd->toc;
769769+ tramp_aix->static_chain = closure;
770770+ closure->cif = cif;
771771+ closure->fun = fun;
772772+ closure->user_data = user_data;
773773+ break;
774774+ }
775775+776776+ default:
777777+ return FFI_BAD_ABI;
778778+ }
779779+780780+ return FFI_OK;
781781+}
782782+783783+#if defined(__ppc__)
784784+ typedef double ldbits[2];
785785+786786+ typedef union
787787+ {
788788+ ldbits lb;
789789+ long double ld;
790790+ } ldu;
791791+#endif
792792+793793+typedef union
794794+{
795795+ float f;
796796+ double d;
797797+} ffi_dblfl;
798798+799799+/* The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the
800800+ address of the closure. After storing the registers that could possibly
801801+ contain parameters to be passed into the stack frame and setting up space
802802+ for a return value, ffi_closure_ASM invokes the following helper function
803803+ to do most of the work. */
804804+int
805805+ffi_closure_helper_DARWIN(
806806+ ffi_closure* closure,
807807+ void* rvalue,
808808+ unsigned long* pgr,
809809+ ffi_dblfl* pfr)
810810+{
811811+ /* rvalue is the pointer to space for return value in closure assembly
812812+ pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
813813+ pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */
814814+815815+#if defined(__ppc__)
816816+ ldu temp_ld;
817817+#endif
818818+819819+ double temp;
820820+ unsigned int i;
821821+ unsigned int nf = 0; /* number of FPRs already used. */
822822+ unsigned int ng = 0; /* number of GPRs already used. */
823823+ ffi_cif* cif = closure->cif;
824824+ long avn = cif->nargs;
825825+ void** avalue = alloca(cif->nargs * sizeof(void*));
826826+ ffi_type** arg_types = cif->arg_types;
827827+828828+ /* Copy the caller's structure return value address so that the closure
829829+ returns the data directly to the caller. */
830830+#if defined(__ppc64__)
831831+ if (cif->rtype->type == FFI_TYPE_STRUCT &&
832832+ ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
833833+#elif defined(__ppc__)
834834+ if (cif->rtype->type == FFI_TYPE_STRUCT)
835835+#else
836836+#error undefined architecture
837837+#endif
838838+ {
839839+ rvalue = (void*)*pgr;
840840+ pgr++;
841841+ ng++;
842842+ }
843843+844844+ /* Grab the addresses of the arguments from the stack frame. */
845845+ for (i = 0; i < avn; i++)
846846+ {
847847+ switch (arg_types[i]->type)
848848+ {
849849+ case FFI_TYPE_SINT8:
850850+ case FFI_TYPE_UINT8:
851851+ avalue[i] = (char*)pgr + MODE_CHOICE(3,7);
852852+ ng++;
853853+ pgr++;
854854+ break;
855855+856856+ case FFI_TYPE_SINT16:
857857+ case FFI_TYPE_UINT16:
858858+ avalue[i] = (char*)pgr + MODE_CHOICE(2,6);
859859+ ng++;
860860+ pgr++;
861861+ break;
862862+863863+#if defined(__ppc__)
864864+ case FFI_TYPE_POINTER:
865865+#endif
866866+ case FFI_TYPE_SINT32:
867867+ case FFI_TYPE_UINT32:
868868+ avalue[i] = (char*)pgr + MODE_CHOICE(0,4);
869869+ ng++;
870870+ pgr++;
871871+872872+ break;
873873+874874+ case FFI_TYPE_STRUCT:
875875+ if (cif->abi == FFI_DARWIN)
876876+ {
877877+#if defined(__ppc64__)
878878+ unsigned int gprSize = 0;
879879+ unsigned int fprSize = 0;
880880+ unsigned int savedFPRSize = fprSize;
881881+882882+ avalue[i] = alloca(arg_types[i]->size);
883883+ ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr,
884884+ &gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL);
885885+886886+ ng += gprSize / sizeof(long);
887887+ pgr += gprSize / sizeof(long);
888888+ pfr += (fprSize - savedFPRSize) / sizeof(double);
889889+890890+#elif defined(__ppc__)
891891+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
892892+ SI 4 bytes) are aligned as if they were those modes. */
893893+ unsigned int size_al = size_al = arg_types[i]->size;
894894+895895+ /* If the first member of the struct is a double, then align
896896+ the struct to double-word. */
897897+ if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
898898+ size_al = ALIGN(arg_types[i]->size, 8);
899899+900900+ if (size_al < 3)
901901+ avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al;
902902+ else
903903+ avalue[i] = (void*)pgr;
904904+905905+ ng += (size_al + 3) / sizeof(long);
906906+ pgr += (size_al + 3) / sizeof(long);
907907+#else
908908+#error undefined architecture
909909+#endif
910910+ }
911911+912912+ break;
913913+914914+#if defined(__ppc64__)
915915+ case FFI_TYPE_POINTER:
916916+#endif
917917+ case FFI_TYPE_SINT64:
918918+ case FFI_TYPE_UINT64:
919919+ /* Long long ints are passed in 1 or 2 GPRs. */
920920+ avalue[i] = pgr;
921921+ ng += MODE_CHOICE(2,1);
922922+ pgr += MODE_CHOICE(2,1);
923923+924924+ break;
925925+926926+ case FFI_TYPE_FLOAT:
927927+ /* A float value consumes a GPR.
928928+ There are 13 64-bit floating point registers. */
929929+ if (nf < NUM_FPR_ARG_REGISTERS)
930930+ {
931931+ temp = pfr->d;
932932+ pfr->f = (float)temp;
933933+ avalue[i] = pfr;
934934+ pfr++;
935935+ }
936936+ else
937937+ avalue[i] = pgr;
938938+939939+ nf++;
940940+ ng++;
941941+ pgr++;
942942+ break;
943943+944944+ case FFI_TYPE_DOUBLE:
945945+ /* A double value consumes one or two GPRs.
946946+ There are 13 64bit floating point registers. */
947947+ if (nf < NUM_FPR_ARG_REGISTERS)
948948+ {
949949+ avalue[i] = pfr;
950950+ pfr++;
951951+ }
952952+ else
953953+ avalue[i] = pgr;
954954+955955+ nf++;
956956+ ng += MODE_CHOICE(2,1);
957957+ pgr += MODE_CHOICE(2,1);
958958+959959+ break;
960960+961961+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
962962+963963+ case FFI_TYPE_LONGDOUBLE:
964964+#if defined(__ppc64__)
965965+ if (nf < NUM_FPR_ARG_REGISTERS)
966966+ {
967967+ avalue[i] = pfr;
968968+ pfr += 2;
969969+ }
970970+#elif defined(__ppc__)
971971+ /* A long double value consumes 2/4 GPRs and 2 FPRs.
972972+ There are 13 64bit floating point registers. */
973973+ if (nf < NUM_FPR_ARG_REGISTERS - 1)
974974+ {
975975+ avalue[i] = pfr;
976976+ pfr += 2;
977977+ }
978978+ /* Here we have the situation where one part of the long double
979979+ is stored in fpr13 and the other part is already on the stack.
980980+ We use a union to pass the long double to avalue[i]. */
981981+ else if (nf == NUM_FPR_ARG_REGISTERS - 1)
982982+ {
983983+ memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0]));
984984+ memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1]));
985985+ avalue[i] = &temp_ld.ld;
986986+ }
987987+#else
988988+#error undefined architecture
989989+#endif
990990+ else
991991+ avalue[i] = pgr;
992992+993993+ nf += 2;
994994+ ng += MODE_CHOICE(4,2);
995995+ pgr += MODE_CHOICE(4,2);
996996+997997+ break;
998998+999999+#endif /* FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE */
10001000+10011001+ default:
10021002+ FFI_ASSERT(0);
10031003+ break;
10041004+ }
10051005+ }
10061006+10071007+ (closure->fun)(cif, rvalue, avalue, closure->user_data);
10081008+10091009+ /* Tell ffi_closure_ASM to perform return type promotions. */
10101010+ return cif->rtype->type;
10111011+}
10121012+10131013+#if defined(__ppc64__)
10141014+10151015+/* ffi64_struct_to_ram_form
10161016+10171017+ Rebuild a struct's natural layout from buffers of concatenated registers.
10181018+ Return the number of registers used.
10191019+ inGPRs[0-7] == r3, inFPRs[0-7] == f1 ...
10201020+*/
10211021+void
10221022+ffi64_struct_to_ram_form(
10231023+ const ffi_type* inType,
10241024+ const char* inGPRs,
10251025+ unsigned int* ioGPRMarker,
10261026+ const char* inFPRs,
10271027+ unsigned int* ioFPRMarker,
10281028+ unsigned int* ioFPRsUsed,
10291029+ char* outStruct, // caller-allocated
10301030+ unsigned int* ioStructMarker)
10311031+{
10321032+ unsigned int srcGMarker = 0;
10331033+ unsigned int srcFMarker = 0;
10341034+ unsigned int savedFMarker = 0;
10351035+ unsigned int fprsUsed = 0;
10361036+ unsigned int savedFPRsUsed = 0;
10371037+ unsigned int destMarker = 0;
10381038+10391039+ static unsigned int recurseCount = 0;
10401040+10411041+ if (ioGPRMarker)
10421042+ srcGMarker = *ioGPRMarker;
10431043+10441044+ if (ioFPRMarker)
10451045+ {
10461046+ srcFMarker = *ioFPRMarker;
10471047+ savedFMarker = srcFMarker;
10481048+ }
10491049+10501050+ if (ioFPRsUsed)
10511051+ {
10521052+ fprsUsed = *ioFPRsUsed;
10531053+ savedFPRsUsed = fprsUsed;
10541054+ }
10551055+10561056+ if (ioStructMarker)
10571057+ destMarker = *ioStructMarker;
10581058+10591059+ size_t i;
10601060+10611061+ switch (inType->size)
10621062+ {
10631063+ case 1: case 2: case 4:
10641064+ srcGMarker += 8 - inType->size;
10651065+ break;
10661066+10671067+ default:
10681068+ break;
10691069+ }
10701070+10711071+ for (i = 0; inType->elements[i] != NULL; i++)
10721072+ {
10731073+ switch (inType->elements[i]->type)
10741074+ {
10751075+ case FFI_TYPE_FLOAT:
10761076+ srcFMarker = ALIGN(srcFMarker, 4);
10771077+ srcGMarker = ALIGN(srcGMarker, 4);
10781078+ destMarker = ALIGN(destMarker, 4);
10791079+10801080+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
10811081+ {
10821082+ *(float*)&outStruct[destMarker] =
10831083+ (float)*(double*)&inFPRs[srcFMarker];
10841084+ srcFMarker += 8;
10851085+ fprsUsed++;
10861086+ }
10871087+ else
10881088+ *(float*)&outStruct[destMarker] =
10891089+ (float)*(double*)&inGPRs[srcGMarker];
10901090+10911091+ srcGMarker += 4;
10921092+ destMarker += 4;
10931093+10941094+ // Skip to next GPR if next element won't fit and we're
10951095+ // not already at a register boundary.
10961096+ if (inType->elements[i + 1] != NULL && (destMarker % 8))
10971097+ {
10981098+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
10991099+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
11001100+ (ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
11011101+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
11021102+ (ALIGN(srcGMarker, 8) - srcGMarker) < 4))
11031103+ srcGMarker = ALIGN(srcGMarker, 8);
11041104+ }
11051105+11061106+ break;
11071107+11081108+ case FFI_TYPE_DOUBLE:
11091109+ srcFMarker = ALIGN(srcFMarker, 8);
11101110+ destMarker = ALIGN(destMarker, 8);
11111111+11121112+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
11131113+ {
11141114+ *(double*)&outStruct[destMarker] =
11151115+ *(double*)&inFPRs[srcFMarker];
11161116+ srcFMarker += 8;
11171117+ fprsUsed++;
11181118+ }
11191119+ else
11201120+ *(double*)&outStruct[destMarker] =
11211121+ *(double*)&inGPRs[srcGMarker];
11221122+11231123+ destMarker += 8;
11241124+11251125+ // Skip next GPR
11261126+ srcGMarker += 8;
11271127+ srcGMarker = ALIGN(srcGMarker, 8);
11281128+11291129+ break;
11301130+11311131+ case FFI_TYPE_LONGDOUBLE:
11321132+ destMarker = ALIGN(destMarker, 16);
11331133+11341134+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
11351135+ {
11361136+ srcFMarker = ALIGN(srcFMarker, 8);
11371137+ srcGMarker = ALIGN(srcGMarker, 8);
11381138+ *(long double*)&outStruct[destMarker] =
11391139+ *(long double*)&inFPRs[srcFMarker];
11401140+ srcFMarker += 16;
11411141+ fprsUsed += 2;
11421142+ }
11431143+ else
11441144+ {
11451145+ srcFMarker = ALIGN(srcFMarker, 16);
11461146+ srcGMarker = ALIGN(srcGMarker, 16);
11471147+ *(long double*)&outStruct[destMarker] =
11481148+ *(long double*)&inGPRs[srcGMarker];
11491149+ }
11501150+11511151+ destMarker += 16;
11521152+11531153+ // Skip next 2 GPRs
11541154+ srcGMarker += 16;
11551155+ srcGMarker = ALIGN(srcGMarker, 8);
11561156+11571157+ break;
11581158+11591159+ case FFI_TYPE_UINT8:
11601160+ case FFI_TYPE_SINT8:
11611161+ {
11621162+ if (inType->alignment == 1) // chars only
11631163+ {
11641164+ if (inType->size == 1)
11651165+ outStruct[destMarker++] = inGPRs[srcGMarker++];
11661166+ else if (inType->size == 2)
11671167+ {
11681168+ outStruct[destMarker++] = inGPRs[srcGMarker++];
11691169+ outStruct[destMarker++] = inGPRs[srcGMarker++];
11701170+ i++;
11711171+ }
11721172+ else
11731173+ {
11741174+ memcpy(&outStruct[destMarker],
11751175+ &inGPRs[srcGMarker], inType->size);
11761176+ srcGMarker += inType->size;
11771177+ destMarker += inType->size;
11781178+ i += inType->size - 1;
11791179+ }
11801180+ }
11811181+ else // chars and other stuff
11821182+ {
11831183+ outStruct[destMarker++] = inGPRs[srcGMarker++];
11841184+11851185+ // Skip to next GPR if next element won't fit and we're
11861186+ // not already at a register boundary.
11871187+ if (inType->elements[i + 1] != NULL && (srcGMarker % 8))
11881188+ {
11891189+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
11901190+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
11911191+ (ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
11921192+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
11931193+ (ALIGN(srcGMarker, 8) - srcGMarker) < 4))
11941194+ srcGMarker = ALIGN(srcGMarker, inType->alignment); // was 8
11951195+ }
11961196+ }
11971197+11981198+ break;
11991199+ }
12001200+12011201+ case FFI_TYPE_UINT16:
12021202+ case FFI_TYPE_SINT16:
12031203+ srcGMarker = ALIGN(srcGMarker, 2);
12041204+ destMarker = ALIGN(destMarker, 2);
12051205+12061206+ *(short*)&outStruct[destMarker] =
12071207+ *(short*)&inGPRs[srcGMarker];
12081208+ srcGMarker += 2;
12091209+ destMarker += 2;
12101210+12111211+ break;
12121212+12131213+ case FFI_TYPE_INT:
12141214+ case FFI_TYPE_UINT32:
12151215+ case FFI_TYPE_SINT32:
12161216+ srcGMarker = ALIGN(srcGMarker, 4);
12171217+ destMarker = ALIGN(destMarker, 4);
12181218+12191219+ *(int*)&outStruct[destMarker] =
12201220+ *(int*)&inGPRs[srcGMarker];
12211221+ srcGMarker += 4;
12221222+ destMarker += 4;
12231223+12241224+ break;
12251225+12261226+ case FFI_TYPE_POINTER:
12271227+ case FFI_TYPE_UINT64:
12281228+ case FFI_TYPE_SINT64:
12291229+ srcGMarker = ALIGN(srcGMarker, 8);
12301230+ destMarker = ALIGN(destMarker, 8);
12311231+12321232+ *(long long*)&outStruct[destMarker] =
12331233+ *(long long*)&inGPRs[srcGMarker];
12341234+ srcGMarker += 8;
12351235+ destMarker += 8;
12361236+12371237+ break;
12381238+12391239+ case FFI_TYPE_STRUCT:
12401240+ recurseCount++;
12411241+ ffi64_struct_to_ram_form(inType->elements[i], inGPRs,
12421242+ &srcGMarker, inFPRs, &srcFMarker, &fprsUsed,
12431243+ outStruct, &destMarker);
12441244+ recurseCount--;
12451245+ break;
12461246+12471247+ default:
12481248+ FFI_ASSERT(0); // unknown element type
12491249+ break;
12501250+ }
12511251+ }
12521252+12531253+ srcGMarker = ALIGN(srcGMarker, inType->alignment);
12541254+12551255+ // Take care of the special case for 16-byte structs, but not for
12561256+ // nested structs.
12571257+ if (recurseCount == 0 && srcGMarker == 16)
12581258+ {
12591259+ *(long double*)&outStruct[0] = *(long double*)&inGPRs[0];
12601260+ srcFMarker = savedFMarker;
12611261+ fprsUsed = savedFPRsUsed;
12621262+ }
12631263+12641264+ if (ioGPRMarker)
12651265+ *ioGPRMarker = ALIGN(srcGMarker, 8);
12661266+12671267+ if (ioFPRMarker)
12681268+ *ioFPRMarker = srcFMarker;
12691269+12701270+ if (ioFPRsUsed)
12711271+ *ioFPRsUsed = fprsUsed;
12721272+12731273+ if (ioStructMarker)
12741274+ *ioStructMarker = ALIGN(destMarker, 8);
12751275+}
12761276+12771277+/* ffi64_struct_to_reg_form
12781278+12791279+ Copy a struct's elements into buffers that can be sliced into registers.
12801280+ Return the sizes of the output buffers in bytes. Pass NULL buffer pointers
12811281+ to calculate size only.
12821282+ outGPRs[0-7] == r3, outFPRs[0-7] == f1 ...
12831283+*/
12841284+void
12851285+ffi64_struct_to_reg_form(
12861286+ const ffi_type* inType,
12871287+ const char* inStruct,
12881288+ unsigned int* ioStructMarker,
12891289+ unsigned int* ioFPRsUsed,
12901290+ char* outGPRs, // caller-allocated
12911291+ unsigned int* ioGPRSize,
12921292+ char* outFPRs, // caller-allocated
12931293+ unsigned int* ioFPRSize)
12941294+{
12951295+ size_t i;
12961296+ unsigned int srcMarker = 0;
12971297+ unsigned int destGMarker = 0;
12981298+ unsigned int destFMarker = 0;
12991299+ unsigned int savedFMarker = 0;
13001300+ unsigned int fprsUsed = 0;
13011301+ unsigned int savedFPRsUsed = 0;
13021302+13031303+ static unsigned int recurseCount = 0;
13041304+13051305+ if (ioStructMarker)
13061306+ srcMarker = *ioStructMarker;
13071307+13081308+ if (ioFPRsUsed)
13091309+ {
13101310+ fprsUsed = *ioFPRsUsed;
13111311+ savedFPRsUsed = fprsUsed;
13121312+ }
13131313+13141314+ if (ioGPRSize)
13151315+ destGMarker = *ioGPRSize;
13161316+13171317+ if (ioFPRSize)
13181318+ {
13191319+ destFMarker = *ioFPRSize;
13201320+ savedFMarker = destFMarker;
13211321+ }
13221322+13231323+ switch (inType->size)
13241324+ {
13251325+ case 1: case 2: case 4:
13261326+ destGMarker += 8 - inType->size;
13271327+ break;
13281328+13291329+ default:
13301330+ break;
13311331+ }
13321332+13331333+ for (i = 0; inType->elements[i] != NULL; i++)
13341334+ {
13351335+ switch (inType->elements[i]->type)
13361336+ {
13371337+ // Shadow floating-point types in GPRs for vararg and pre-ANSI
13381338+ // functions.
13391339+ case FFI_TYPE_FLOAT:
13401340+ // Nudge markers to next 4/8-byte boundary
13411341+ srcMarker = ALIGN(srcMarker, 4);
13421342+ destGMarker = ALIGN(destGMarker, 4);
13431343+ destFMarker = ALIGN(destFMarker, 8);
13441344+13451345+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
13461346+ {
13471347+ if (outFPRs != NULL && inStruct != NULL)
13481348+ *(double*)&outFPRs[destFMarker] =
13491349+ (double)*(float*)&inStruct[srcMarker];
13501350+13511351+ destFMarker += 8;
13521352+ fprsUsed++;
13531353+ }
13541354+13551355+ if (outGPRs != NULL && inStruct != NULL)
13561356+ *(double*)&outGPRs[destGMarker] =
13571357+ (double)*(float*)&inStruct[srcMarker];
13581358+13591359+ srcMarker += 4;
13601360+ destGMarker += 4;
13611361+13621362+ // Skip to next GPR if next element won't fit and we're
13631363+ // not already at a register boundary.
13641364+ if (inType->elements[i + 1] != NULL && (srcMarker % 8))
13651365+ {
13661366+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
13671367+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
13681368+ (ALIGN(destGMarker, 8) - destGMarker) < 2) &&
13691369+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
13701370+ (ALIGN(destGMarker, 8) - destGMarker) < 4))
13711371+ destGMarker = ALIGN(destGMarker, 8);
13721372+ }
13731373+13741374+ break;
13751375+13761376+ case FFI_TYPE_DOUBLE:
13771377+ srcMarker = ALIGN(srcMarker, 8);
13781378+ destFMarker = ALIGN(destFMarker, 8);
13791379+13801380+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
13811381+ {
13821382+ if (outFPRs != NULL && inStruct != NULL)
13831383+ *(double*)&outFPRs[destFMarker] =
13841384+ *(double*)&inStruct[srcMarker];
13851385+13861386+ destFMarker += 8;
13871387+ fprsUsed++;
13881388+ }
13891389+13901390+ if (outGPRs != NULL && inStruct != NULL)
13911391+ *(double*)&outGPRs[destGMarker] =
13921392+ *(double*)&inStruct[srcMarker];
13931393+13941394+ srcMarker += 8;
13951395+13961396+ // Skip next GPR
13971397+ destGMarker += 8;
13981398+ destGMarker = ALIGN(destGMarker, 8);
13991399+14001400+ break;
14011401+14021402+ case FFI_TYPE_LONGDOUBLE:
14031403+ srcMarker = ALIGN(srcMarker, 16);
14041404+14051405+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
14061406+ {
14071407+ destFMarker = ALIGN(destFMarker, 8);
14081408+ destGMarker = ALIGN(destGMarker, 8);
14091409+14101410+ if (outFPRs != NULL && inStruct != NULL)
14111411+ *(long double*)&outFPRs[destFMarker] =
14121412+ *(long double*)&inStruct[srcMarker];
14131413+14141414+ if (outGPRs != NULL && inStruct != NULL)
14151415+ *(long double*)&outGPRs[destGMarker] =
14161416+ *(long double*)&inStruct[srcMarker];
14171417+14181418+ destFMarker += 16;
14191419+ fprsUsed += 2;
14201420+ }
14211421+ else
14221422+ {
14231423+ destGMarker = ALIGN(destGMarker, 16);
14241424+14251425+ if (outGPRs != NULL && inStruct != NULL)
14261426+ *(long double*)&outGPRs[destGMarker] =
14271427+ *(long double*)&inStruct[srcMarker];
14281428+ }
14291429+14301430+ srcMarker += 16;
14311431+ destGMarker += 16; // Skip next 2 GPRs
14321432+ destGMarker = ALIGN(destGMarker, 8); // was 16
14331433+14341434+ break;
14351435+14361436+ case FFI_TYPE_UINT8:
14371437+ case FFI_TYPE_SINT8:
14381438+ if (inType->alignment == 1) // bytes only
14391439+ {
14401440+ if (inType->size == 1)
14411441+ {
14421442+ if (outGPRs != NULL && inStruct != NULL)
14431443+ outGPRs[destGMarker] = inStruct[srcMarker];
14441444+14451445+ srcMarker++;
14461446+ destGMarker++;
14471447+ }
14481448+ else if (inType->size == 2)
14491449+ {
14501450+ if (outGPRs != NULL && inStruct != NULL)
14511451+ {
14521452+ outGPRs[destGMarker] = inStruct[srcMarker];
14531453+ outGPRs[destGMarker + 1] = inStruct[srcMarker + 1];
14541454+ }
14551455+14561456+ srcMarker += 2;
14571457+ destGMarker += 2;
14581458+14591459+ i++;
14601460+ }
14611461+ else
14621462+ {
14631463+ if (outGPRs != NULL && inStruct != NULL)
14641464+ {
14651465+ // Avoid memcpy for small chunks.
14661466+ if (inType->size <= sizeof(long))
14671467+ *(long*)&outGPRs[destGMarker] =
14681468+ *(long*)&inStruct[srcMarker];
14691469+ else
14701470+ memcpy(&outGPRs[destGMarker],
14711471+ &inStruct[srcMarker], inType->size);
14721472+ }
14731473+14741474+ srcMarker += inType->size;
14751475+ destGMarker += inType->size;
14761476+ i += inType->size - 1;
14771477+ }
14781478+ }
14791479+ else // bytes and other stuff
14801480+ {
14811481+ if (outGPRs != NULL && inStruct != NULL)
14821482+ outGPRs[destGMarker] = inStruct[srcMarker];
14831483+14841484+ srcMarker++;
14851485+ destGMarker++;
14861486+14871487+ // Skip to next GPR if next element won't fit and we're
14881488+ // not already at a register boundary.
14891489+ if (inType->elements[i + 1] != NULL && (destGMarker % 8))
14901490+ {
14911491+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
14921492+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
14931493+ (ALIGN(destGMarker, 8) - destGMarker) < 2) &&
14941494+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
14951495+ (ALIGN(destGMarker, 8) - destGMarker) < 4))
14961496+ destGMarker = ALIGN(destGMarker, inType->alignment); // was 8
14971497+ }
14981498+ }
14991499+15001500+ break;
15011501+15021502+ case FFI_TYPE_UINT16:
15031503+ case FFI_TYPE_SINT16:
15041504+ srcMarker = ALIGN(srcMarker, 2);
15051505+ destGMarker = ALIGN(destGMarker, 2);
15061506+15071507+ if (outGPRs != NULL && inStruct != NULL)
15081508+ *(short*)&outGPRs[destGMarker] =
15091509+ *(short*)&inStruct[srcMarker];
15101510+15111511+ srcMarker += 2;
15121512+ destGMarker += 2;
15131513+15141514+ if (inType->elements[i + 1] == NULL)
15151515+ destGMarker = ALIGN(destGMarker, inType->alignment);
15161516+15171517+ break;
15181518+15191519+ case FFI_TYPE_INT:
15201520+ case FFI_TYPE_UINT32:
15211521+ case FFI_TYPE_SINT32:
15221522+ srcMarker = ALIGN(srcMarker, 4);
15231523+ destGMarker = ALIGN(destGMarker, 4);
15241524+15251525+ if (outGPRs != NULL && inStruct != NULL)
15261526+ *(int*)&outGPRs[destGMarker] =
15271527+ *(int*)&inStruct[srcMarker];
15281528+15291529+ srcMarker += 4;
15301530+ destGMarker += 4;
15311531+15321532+ break;
15331533+15341534+ case FFI_TYPE_POINTER:
15351535+ case FFI_TYPE_UINT64:
15361536+ case FFI_TYPE_SINT64:
15371537+ srcMarker = ALIGN(srcMarker, 8);
15381538+ destGMarker = ALIGN(destGMarker, 8);
15391539+15401540+ if (outGPRs != NULL && inStruct != NULL)
15411541+ *(long long*)&outGPRs[destGMarker] =
15421542+ *(long long*)&inStruct[srcMarker];
15431543+15441544+ srcMarker += 8;
15451545+ destGMarker += 8;
15461546+15471547+ if (inType->elements[i + 1] == NULL)
15481548+ destGMarker = ALIGN(destGMarker, inType->alignment);
15491549+15501550+ break;
15511551+15521552+ case FFI_TYPE_STRUCT:
15531553+ recurseCount++;
15541554+ ffi64_struct_to_reg_form(inType->elements[i],
15551555+ inStruct, &srcMarker, &fprsUsed, outGPRs,
15561556+ &destGMarker, outFPRs, &destFMarker);
15571557+ recurseCount--;
15581558+ break;
15591559+15601560+ default:
15611561+ FFI_ASSERT(0);
15621562+ break;
15631563+ }
15641564+ }
15651565+15661566+ destGMarker = ALIGN(destGMarker, inType->alignment);
15671567+15681568+ // Take care of the special case for 16-byte structs, but not for
15691569+ // nested structs.
15701570+ if (recurseCount == 0 && destGMarker == 16)
15711571+ {
15721572+ if (outGPRs != NULL && inStruct != NULL)
15731573+ *(long double*)&outGPRs[0] = *(long double*)&inStruct[0];
15741574+15751575+ destFMarker = savedFMarker;
15761576+ fprsUsed = savedFPRsUsed;
15771577+ }
15781578+15791579+ if (ioStructMarker)
15801580+ *ioStructMarker = ALIGN(srcMarker, 8);
15811581+15821582+ if (ioFPRsUsed)
15831583+ *ioFPRsUsed = fprsUsed;
15841584+15851585+ if (ioGPRSize)
15861586+ *ioGPRSize = ALIGN(destGMarker, 8);
15871587+15881588+ if (ioFPRSize)
15891589+ *ioFPRSize = ALIGN(destFMarker, 8);
15901590+}
15911591+15921592+/* ffi64_stret_needs_ptr
15931593+15941594+ Determine whether a returned struct needs a pointer in r3 or can fit
15951595+ in registers.
15961596+*/
15971597+15981598+bool
15991599+ffi64_stret_needs_ptr(
16001600+ const ffi_type* inType,
16011601+ unsigned short* ioGPRCount,
16021602+ unsigned short* ioFPRCount)
16031603+{
16041604+ // Obvious case first- struct is larger than combined FPR size.
16051605+ if (inType->size > 14 * 8)
16061606+ return true;
16071607+16081608+ // Now the struct can physically fit in registers, determine if it
16091609+ // also fits logically.
16101610+ bool needsPtr = false;
16111611+ unsigned short gprsUsed = 0;
16121612+ unsigned short fprsUsed = 0;
16131613+ size_t i;
16141614+16151615+ if (ioGPRCount)
16161616+ gprsUsed = *ioGPRCount;
16171617+16181618+ if (ioFPRCount)
16191619+ fprsUsed = *ioFPRCount;
16201620+16211621+ for (i = 0; inType->elements[i] != NULL && !needsPtr; i++)
16221622+ {
16231623+ switch (inType->elements[i]->type)
16241624+ {
16251625+ case FFI_TYPE_FLOAT:
16261626+ case FFI_TYPE_DOUBLE:
16271627+ gprsUsed++;
16281628+ fprsUsed++;
16291629+16301630+ if (fprsUsed > 13)
16311631+ needsPtr = true;
16321632+16331633+ break;
16341634+16351635+ case FFI_TYPE_LONGDOUBLE:
16361636+ gprsUsed += 2;
16371637+ fprsUsed += 2;
16381638+16391639+ if (fprsUsed > 14)
16401640+ needsPtr = true;
16411641+16421642+ break;
16431643+16441644+ case FFI_TYPE_UINT8:
16451645+ case FFI_TYPE_SINT8:
16461646+ {
16471647+ gprsUsed++;
16481648+16491649+ if (gprsUsed > 8)
16501650+ {
16511651+ needsPtr = true;
16521652+ break;
16531653+ }
16541654+16551655+ if (inType->elements[i + 1] == NULL) // last byte in the struct
16561656+ break;
16571657+16581658+ // Count possible contiguous bytes ahead, up to 8.
16591659+ unsigned short j;
16601660+16611661+ for (j = 1; j < 8; j++)
16621662+ {
16631663+ if (inType->elements[i + j] == NULL ||
16641664+ !FFI_TYPE_1_BYTE(inType->elements[i + j]->type))
16651665+ break;
16661666+ }
16671667+16681668+ i += j - 1; // allow for i++ before the test condition
16691669+16701670+ break;
16711671+ }
16721672+16731673+ case FFI_TYPE_UINT16:
16741674+ case FFI_TYPE_SINT16:
16751675+ case FFI_TYPE_INT:
16761676+ case FFI_TYPE_UINT32:
16771677+ case FFI_TYPE_SINT32:
16781678+ case FFI_TYPE_POINTER:
16791679+ case FFI_TYPE_UINT64:
16801680+ case FFI_TYPE_SINT64:
16811681+ gprsUsed++;
16821682+16831683+ if (gprsUsed > 8)
16841684+ needsPtr = true;
16851685+16861686+ break;
16871687+16881688+ case FFI_TYPE_STRUCT:
16891689+ needsPtr = ffi64_stret_needs_ptr(
16901690+ inType->elements[i], &gprsUsed, &fprsUsed);
16911691+16921692+ break;
16931693+16941694+ default:
16951695+ FFI_ASSERT(0);
16961696+ break;
16971697+ }
16981698+ }
16991699+17001700+ if (ioGPRCount)
17011701+ *ioGPRCount = gprsUsed;
17021702+17031703+ if (ioFPRCount)
17041704+ *ioFPRCount = fprsUsed;
17051705+17061706+ return needsPtr;
17071707+}
17081708+17091709+/* ffi64_data_size
17101710+17111711+ Calculate the size in bytes of an ffi type.
17121712+*/
17131713+17141714+unsigned int
17151715+ffi64_data_size(
17161716+ const ffi_type* inType)
17171717+{
17181718+ unsigned int size = 0;
17191719+17201720+ switch (inType->type)
17211721+ {
17221722+ case FFI_TYPE_UINT8:
17231723+ case FFI_TYPE_SINT8:
17241724+ size = 1;
17251725+ break;
17261726+17271727+ case FFI_TYPE_UINT16:
17281728+ case FFI_TYPE_SINT16:
17291729+ size = 2;
17301730+ break;
17311731+17321732+ case FFI_TYPE_INT:
17331733+ case FFI_TYPE_UINT32:
17341734+ case FFI_TYPE_SINT32:
17351735+ case FFI_TYPE_FLOAT:
17361736+ size = 4;
17371737+ break;
17381738+17391739+ case FFI_TYPE_POINTER:
17401740+ case FFI_TYPE_UINT64:
17411741+ case FFI_TYPE_SINT64:
17421742+ case FFI_TYPE_DOUBLE:
17431743+ size = 8;
17441744+ break;
17451745+17461746+ case FFI_TYPE_LONGDOUBLE:
17471747+ size = 16;
17481748+ break;
17491749+17501750+ case FFI_TYPE_STRUCT:
17511751+ ffi64_struct_to_reg_form(
17521752+ inType, NULL, NULL, NULL, NULL, &size, NULL, NULL);
17531753+ break;
17541754+17551755+ case FFI_TYPE_VOID:
17561756+ break;
17571757+17581758+ default:
17591759+ FFI_ASSERT(0);
17601760+ break;
17611761+ }
17621762+17631763+ return size;
17641764+}
17651765+17661766+#endif /* defined(__ppc64__) */
17671767+#endif /* __ppc__ || __ppc64__ */
+418
src/libffi/powerpc/ppc64-darwin_closure.S
···11+#if defined(__ppc64__)
22+33+/* -----------------------------------------------------------------------
44+ ppc64-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
55+ Inc. based on ppc_closure.S
66+77+ PowerPC Assembly glue.
88+99+ Permission is hereby granted, free of charge, to any person obtaining
1010+ a copy of this software and associated documentation files (the
1111+ ``Software''), to deal in the Software without restriction, including
1212+ without limitation the rights to use, copy, modify, merge, publish,
1313+ distribute, sublicense, and/or sell copies of the Software, and to
1414+ permit persons to whom the Software is furnished to do so, subject to
1515+ the following conditions:
1616+1717+ The above copyright notice and this permission notice shall be included
1818+ in all copies or substantial portions of the Software.
1919+2020+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
2121+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2222+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2323+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
2424+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2525+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2626+ OTHER DEALINGS IN THE SOFTWARE.
2727+ ----------------------------------------------------------------------- */
2828+2929+#define LIBFFI_ASM
3030+3131+#include <ffi.h>
3232+#include <ppc-ffitarget.h> // for FFI_TRAMPOLINE_SIZE
3333+#include <ppc-darwin.h>
3434+#include <architecture/ppc/mode_independent_asm.h>
3535+3636+ .file "ppc64-darwin_closure.S"
3737+.text
3838+ .align LOG2_GPR_BYTES
3939+ .globl _ffi_closure_ASM
4040+4141+.text
4242+ .align LOG2_GPR_BYTES
4343+4444+_ffi_closure_ASM:
4545+LFB1:
4646+ mflr r0
4747+ stg r0,SF_RETURN(r1) // save return address
4848+4949+ // Save GPRs 3 - 10 (aligned to 8) in the parents outgoing area.
5050+ stg r3,SF_ARG1(r1)
5151+ stg r4,SF_ARG2(r1)
5252+ stg r5,SF_ARG3(r1)
5353+ stg r6,SF_ARG4(r1)
5454+ stg r7,SF_ARG5(r1)
5555+ stg r8,SF_ARG6(r1)
5656+ stg r9,SF_ARG7(r1)
5757+ stg r10,SF_ARG8(r1)
5858+5959+LCFI0:
6060+/* 48 bytes (Linkage Area)
6161+ 64 bytes (outgoing parameter area, always reserved)
6262+ 112 bytes (14*8 for incoming FPR)
6363+ ? bytes (result)
6464+ 112 bytes (14*8 for outgoing FPR)
6565+ 16 bytes (2 saved registers)
6666+ 352 + ? total bytes
6767+*/
6868+6969+ std r31,-8(r1) // Save registers we use.
7070+ std r30,-16(r1)
7171+ mr r30,r1 // Save the old SP.
7272+ mr r31,r11 // Save the ffi_closure around ffi64_data_size.
7373+7474+ // Calculate the space we need.
7575+ stdu r1,-SF_MINSIZE(r1)
7676+ ld r3,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif*
7777+ ld r3,16(r3) // ffi_cif->rtype*
7878+ bl Lffi64_data_size$stub
7979+ ld r1,0(r1)
8080+8181+ addi r3,r3,352 // Add our overhead.
8282+ neg r3,r3
8383+ li r0,-32 // Align to 32 bytes.
8484+ and r3,r3,r0
8585+ stdux r1,r1,r3 // Grow the stack.
8686+8787+ mr r11,r31 // Copy the ffi_closure back.
8888+8989+LCFI1:
9090+ // We want to build up an area for the parameters passed
9191+ // in registers. (both floating point and integer)
9292+9393+/* 320 bytes (callee stack frame aligned to 32)
9494+ 48 bytes (caller linkage area)
9595+ 368 (start of caller parameter area aligned to 8)
9696+*/
9797+9898+ // Save FPRs 1 - 14. (aligned to 8)
9999+ stfd f1,112(r1)
100100+ stfd f2,120(r1)
101101+ stfd f3,128(r1)
102102+ stfd f4,136(r1)
103103+ stfd f5,144(r1)
104104+ stfd f6,152(r1)
105105+ stfd f7,160(r1)
106106+ stfd f8,168(r1)
107107+ stfd f9,176(r1)
108108+ stfd f10,184(r1)
109109+ stfd f11,192(r1)
110110+ stfd f12,200(r1)
111111+ stfd f13,208(r1)
112112+ stfd f14,216(r1)
113113+114114+ // Set up registers for the routine that actually does the work.
115115+ mr r3,r11 // context pointer from the trampoline
116116+ addi r4,r1,224 // result storage
117117+ addi r5,r30,SF_ARG1 // saved GPRs
118118+ addi r6,r1,112 // saved FPRs
119119+ bl Lffi_closure_helper_DARWIN$stub
120120+121121+ // Look the proper starting point in table
122122+ // by using return type as an offset.
123123+ addi r5,r1,224 // Get pointer to results area.
124124+ bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR.
125125+ mflr r4 // Move to r4.
126126+ slwi r3,r3,4 // Now multiply return type by 16.
127127+ add r3,r3,r4 // Add contents of table to table address.
128128+ mtctr r3
129129+ bctr
130130+131131+LFE1:
132132+ // Each of the ret_typeX code fragments has to be exactly 16 bytes long
133133+ // (4 instructions). For cache effectiveness we align to a 16 byte
134134+ // boundary first.
135135+ .align 4
136136+ nop
137137+ nop
138138+ nop
139139+140140+Lget_ret_type0_addr:
141141+ blrl
142142+143143+// case FFI_TYPE_VOID
144144+Lret_type0:
145145+ b Lfinish
146146+ nop
147147+ nop
148148+ nop
149149+150150+// case FFI_TYPE_INT
151151+Lret_type1:
152152+ lwz r3,4(r5)
153153+ b Lfinish
154154+ nop
155155+ nop
156156+157157+// case FFI_TYPE_FLOAT
158158+Lret_type2:
159159+ lfs f1,0(r5)
160160+ b Lfinish
161161+ nop
162162+ nop
163163+164164+// case FFI_TYPE_DOUBLE
165165+Lret_type3:
166166+ lfd f1,0(r5)
167167+ b Lfinish
168168+ nop
169169+ nop
170170+171171+// case FFI_TYPE_LONGDOUBLE
172172+Lret_type4:
173173+ lfd f1,0(r5)
174174+ lfd f2,8(r5)
175175+ b Lfinish
176176+ nop
177177+178178+// case FFI_TYPE_UINT8
179179+Lret_type5:
180180+ lbz r3,7(r5)
181181+ b Lfinish
182182+ nop
183183+ nop
184184+185185+// case FFI_TYPE_SINT8
186186+Lret_type6:
187187+ lbz r3,7(r5)
188188+ extsb r3,r3
189189+ b Lfinish
190190+ nop
191191+192192+// case FFI_TYPE_UINT16
193193+Lret_type7:
194194+ lhz r3,6(r5)
195195+ b Lfinish
196196+ nop
197197+ nop
198198+199199+// case FFI_TYPE_SINT16
200200+Lret_type8:
201201+ lha r3,6(r5)
202202+ b Lfinish
203203+ nop
204204+ nop
205205+206206+// case FFI_TYPE_UINT32
207207+Lret_type9: // same as Lret_type1
208208+ lwz r3,4(r5)
209209+ b Lfinish
210210+ nop
211211+ nop
212212+213213+// case FFI_TYPE_SINT32
214214+Lret_type10: // same as Lret_type1
215215+ lwz r3,4(r5)
216216+ b Lfinish
217217+ nop
218218+ nop
219219+220220+// case FFI_TYPE_UINT64
221221+Lret_type11:
222222+ ld r3,0(r5)
223223+ b Lfinish
224224+ nop
225225+ nop
226226+227227+// case FFI_TYPE_SINT64
228228+Lret_type12: // same as Lret_type11
229229+ ld r3,0(r5)
230230+ b Lfinish
231231+ nop
232232+ nop
233233+234234+// case FFI_TYPE_STRUCT
235235+Lret_type13:
236236+ b Lret_struct
237237+ nop
238238+ nop
239239+ nop
240240+241241+// ** End 16-byte aligned cases **
242242+// case FFI_TYPE_POINTER
243243+// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types
244244+// are added in future, the following code will need to be updated and
245245+// padded to 16 bytes.
246246+Lret_type14:
247247+ lg r3,0(r5)
248248+ b Lfinish
249249+250250+// copy struct into registers
251251+Lret_struct:
252252+ ld r31,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif*
253253+ ld r3,16(r31) // ffi_cif->rtype*
254254+ ld r31,24(r31) // ffi_cif->flags
255255+ mr r4,r5 // copy struct* to 2nd arg
256256+ addi r7,r1,SF_ARG9 // GPR return area
257257+ addi r9,r30,-16-(14*8) // FPR return area
258258+ li r5,0 // struct offset ptr (NULL)
259259+ li r6,0 // FPR used count ptr (NULL)
260260+ li r8,0 // GPR return area size ptr (NULL)
261261+ li r10,0 // FPR return area size ptr (NULL)
262262+ bl Lffi64_struct_to_reg_form$stub
263263+264264+ // Load GPRs
265265+ ld r3,SF_ARG9(r1)
266266+ ld r4,SF_ARG10(r1)
267267+ ld r5,SF_ARG11(r1)
268268+ ld r6,SF_ARG12(r1)
269269+ nop
270270+ ld r7,SF_ARG13(r1)
271271+ ld r8,SF_ARG14(r1)
272272+ ld r9,SF_ARG15(r1)
273273+ ld r10,SF_ARG16(r1)
274274+ nop
275275+276276+ // Load FPRs
277277+ mtcrf 0x2,r31
278278+ bf 26,Lfinish
279279+ lfd f1,-16-(14*8)(r30)
280280+ lfd f2,-16-(13*8)(r30)
281281+ lfd f3,-16-(12*8)(r30)
282282+ lfd f4,-16-(11*8)(r30)
283283+ nop
284284+ lfd f5,-16-(10*8)(r30)
285285+ lfd f6,-16-(9*8)(r30)
286286+ lfd f7,-16-(8*8)(r30)
287287+ lfd f8,-16-(7*8)(r30)
288288+ nop
289289+ lfd f9,-16-(6*8)(r30)
290290+ lfd f10,-16-(5*8)(r30)
291291+ lfd f11,-16-(4*8)(r30)
292292+ lfd f12,-16-(3*8)(r30)
293293+ nop
294294+ lfd f13,-16-(2*8)(r30)
295295+ lfd f14,-16-(1*8)(r30)
296296+ // Fall through
297297+298298+// case done
299299+Lfinish:
300300+ lg r1,0(r1) // Restore stack pointer.
301301+ ld r31,-8(r1) // Restore registers we used.
302302+ ld r30,-16(r1)
303303+ lg r0,SF_RETURN(r1) // Get return address.
304304+ mtlr r0 // Reset link register.
305305+ blr
306306+307307+// END(ffi_closure_ASM)
308308+309309+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
310310+EH_frame1:
311311+ .set L$set$0,LECIE1-LSCIE1
312312+ .long L$set$0 ; Length of Common Information Entry
313313+LSCIE1:
314314+ .long 0x0 ; CIE Identifier Tag
315315+ .byte 0x1 ; CIE Version
316316+ .ascii "zR\0" ; CIE Augmentation
317317+ .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
318318+ .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor
319319+ .byte 0x41 ; CIE RA Column
320320+ .byte 0x1 ; uleb128 0x1; Augmentation size
321321+ .byte 0x10 ; FDE Encoding (pcrel)
322322+ .byte 0xc ; DW_CFA_def_cfa
323323+ .byte 0x1 ; uleb128 0x1
324324+ .byte 0x0 ; uleb128 0x0
325325+ .align LOG2_GPR_BYTES
326326+LECIE1:
327327+.globl _ffi_closure_ASM.eh
328328+_ffi_closure_ASM.eh:
329329+LSFDE1:
330330+ .set L$set$1,LEFDE1-LASFDE1
331331+ .long L$set$1 ; FDE Length
332332+333333+LASFDE1:
334334+ .long LASFDE1-EH_frame1 ; FDE CIE offset
335335+ .g_long LFB1-. ; FDE initial location
336336+ .set L$set$3,LFE1-LFB1
337337+ .g_long L$set$3 ; FDE address range
338338+ .byte 0x0 ; uleb128 0x0; Augmentation size
339339+ .byte 0x4 ; DW_CFA_advance_loc4
340340+ .set L$set$3,LCFI1-LCFI0
341341+ .long L$set$3
342342+ .byte 0xe ; DW_CFA_def_cfa_offset
343343+ .byte 176,1 ; uleb128 176
344344+ .byte 0x4 ; DW_CFA_advance_loc4
345345+ .set L$set$4,LCFI0-LFB1
346346+ .long L$set$4
347347+ .byte 0x11 ; DW_CFA_offset_extended_sf
348348+ .byte 0x41 ; uleb128 0x41
349349+ .byte 0x7e ; sleb128 -2
350350+ .align LOG2_GPR_BYTES
351351+352352+LEFDE1:
353353+.data
354354+ .align LOG2_GPR_BYTES
355355+LDFCM0:
356356+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
357357+ .align LOG2_GPR_BYTES
358358+359359+Lffi_closure_helper_DARWIN$stub:
360360+ .indirect_symbol _ffi_closure_helper_DARWIN
361361+ mflr r0
362362+ bcl 20,31,LO$ffi_closure_helper_DARWIN
363363+364364+LO$ffi_closure_helper_DARWIN:
365365+ mflr r11
366366+ addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)
367367+ mtlr r0
368368+ lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11)
369369+ mtctr r12
370370+ bctr
371371+372372+.lazy_symbol_pointer
373373+L_ffi_closure_helper_DARWIN$lazy_ptr:
374374+ .indirect_symbol _ffi_closure_helper_DARWIN
375375+ .g_long dyld_stub_binding_helper
376376+377377+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
378378+ .align LOG2_GPR_BYTES
379379+380380+Lffi64_struct_to_reg_form$stub:
381381+ .indirect_symbol _ffi64_struct_to_reg_form
382382+ mflr r0
383383+ bcl 20,31,LO$ffi64_struct_to_reg_form
384384+385385+LO$ffi64_struct_to_reg_form:
386386+ mflr r11
387387+ addis r11,r11,ha16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form)
388388+ mtlr r0
389389+ lgu r12,lo16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form)(r11)
390390+ mtctr r12
391391+ bctr
392392+393393+.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
394394+ .align LOG2_GPR_BYTES
395395+396396+Lffi64_data_size$stub:
397397+ .indirect_symbol _ffi64_data_size
398398+ mflr r0
399399+ bcl 20,31,LO$ffi64_data_size
400400+401401+LO$ffi64_data_size:
402402+ mflr r11
403403+ addis r11,r11,ha16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size)
404404+ mtlr r0
405405+ lgu r12,lo16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size)(r11)
406406+ mtctr r12
407407+ bctr
408408+409409+.lazy_symbol_pointer
410410+L_ffi64_struct_to_reg_form$lazy_ptr:
411411+ .indirect_symbol _ffi64_struct_to_reg_form
412412+ .g_long dyld_stub_binding_helper
413413+414414+L_ffi64_data_size$lazy_ptr:
415415+ .indirect_symbol _ffi64_data_size
416416+ .g_long dyld_stub_binding_helper
417417+418418+#endif // __ppc64__
+115
src/libffi/types.c
···11+/* -----------------------------------------------------------------------
22+ types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
33+44+ Predefined ffi_types needed by libffi.
55+66+ Permission is hereby granted, free of charge, to any person obtaining
77+ a copy of this software and associated documentation files (the
88+ ``Software''), to deal in the Software without restriction, including
99+ without limitation the rights to use, copy, modify, merge, publish,
1010+ distribute, sublicense, and/or sell copies of the Software, and to
1111+ permit persons to whom the Software is furnished to do so, subject to
1212+ the following conditions:
1313+1414+ The above copyright notice and this permission notice shall be included
1515+ in all copies or substantial portions of the Software.
1616+1717+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1818+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1919+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2020+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2121+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2222+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2323+ OTHER DEALINGS IN THE SOFTWARE.
2424+ ----------------------------------------------------------------------- */
2525+2626+#include <ffi.h>
2727+#include <ffi_common.h>
2828+2929+/* Type definitions */
3030+#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) \
3131+ ffi_type ffi_type_##n = { s, a, t, NULL }
3232+#define FFI_AGGREGATE_TYPEDEF(n, e) \
3333+ ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e }
3434+3535+FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8);
3636+FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8);
3737+FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16);
3838+FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16);
3939+FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
4040+FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
4141+FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
4242+4343+/* Size and alignment are fake here. They must not be 0. */
4444+FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID);
4545+4646+#if defined ALPHA || defined SPARC64 || defined X86_64 || \
4747+ defined S390X || defined IA64 || defined POWERPC64
4848+FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
4949+#else
5050+FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
5151+#endif
5252+5353+#if defined X86 || defined ARM || defined M68K || defined(X86_DARWIN)
5454+5555+# ifdef X86_64
5656+ FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
5757+ FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
5858+# else
5959+ FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
6060+ FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
6161+# endif
6262+6363+#elif defined(POWERPC_DARWIN)
6464+FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
6565+FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
6666+#elif defined SH
6767+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
6868+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
6969+#else
7070+FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
7171+FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
7272+#endif
7373+7474+#if defined X86 || defined X86_WIN32 || defined M68K || defined(X86_DARWIN)
7575+7676+# if defined X86_WIN32 || defined X86_64
7777+ FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
7878+# else
7979+ FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
8080+# endif
8181+8282+# ifdef X86_DARWIN
8383+ FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
8484+# else
8585+ FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
8686+# endif
8787+8888+#elif defined ARM || defined SH || defined POWERPC_AIX
8989+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
9090+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
9191+#elif defined POWERPC_DARWIN
9292+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
9393+9494+# if __GNUC__ >= 4
9595+ FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
9696+# else
9797+ FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE);
9898+# endif
9999+100100+#elif defined SPARC
101101+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
102102+103103+# ifdef SPARC64
104104+ FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
105105+# else
106106+ FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
107107+# endif
108108+109109+#elif defined X86_64 || defined POWERPC64
110110+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
111111+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
112112+#else
113113+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
114114+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE);
115115+#endif
+416
src/libffi/x86/darwin64.S
···11+/* -----------------------------------------------------------------------
22+ darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc.
33+ derived from unix64.S
44+55+ x86-64 Foreign Function Interface for Darwin.
66+77+ Permission is hereby granted, free of charge, to any person obtaining
88+ a copy of this software and associated documentation files (the
99+ ``Software''), to deal in the Software without restriction, including
1010+ without limitation the rights to use, copy, modify, merge, publish,
1111+ distribute, sublicense, and/or sell copies of the Software, and to
1212+ permit persons to whom the Software is furnished to do so, subject to
1313+ the following conditions:
1414+1515+ The above copyright notice and this permission notice shall be included
1616+ in all copies or substantial portions of the Software.
1717+1818+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1919+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2020+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2121+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
2222+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2323+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2424+ OTHER DEALINGS IN THE SOFTWARE.
2525+ ----------------------------------------------------------------------- */
2626+2727+#ifdef __x86_64__
2828+#define LIBFFI_ASM
2929+#include <fficonfig.h>
3030+#include <ffi.h>
3131+3232+ .file "darwin64.S"
3333+.text
3434+3535+/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
3636+ void *raddr, void (*fnaddr)());
3737+3838+ Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
3939+ for this function. This has been allocated by ffi_call. We also
4040+ deallocate some of the stack that has been alloca'd. */
4141+4242+ .align 8
4343+ .globl _ffi_call_unix64
4444+4545+_ffi_call_unix64:
4646+LUW0:
4747+ movq (%rsp), %r10 /* Load return address. */
4848+ leaq (%rdi, %rsi), %rax /* Find local stack base. */
4949+ movq %rdx, (%rax) /* Save flags. */
5050+ movq %rcx, 8(%rax) /* Save raddr. */
5151+ movq %rbp, 16(%rax) /* Save old frame pointer. */
5252+ movq %r10, 24(%rax) /* Relocate return address. */
5353+ movq %rax, %rbp /* Finalize local stack frame. */
5454+LUW1:
5555+ movq %rdi, %r10 /* Save a copy of the register area. */
5656+ movq %r8, %r11 /* Save a copy of the target fn. */
5757+ movl %r9d, %eax /* Set number of SSE registers. */
5858+5959+ /* Load up all argument registers. */
6060+ movq (%r10), %rdi
6161+ movq 8(%r10), %rsi
6262+ movq 16(%r10), %rdx
6363+ movq 24(%r10), %rcx
6464+ movq 32(%r10), %r8
6565+ movq 40(%r10), %r9
6666+ testl %eax, %eax
6767+ jnz Lload_sse
6868+Lret_from_load_sse:
6969+7070+ /* Deallocate the reg arg area. */
7171+ leaq 176(%r10), %rsp
7272+7373+ /* Call the user function. */
7474+ call *%r11
7575+7676+ /* Deallocate stack arg area; local stack frame in redzone. */
7777+ leaq 24(%rbp), %rsp
7878+7979+ movq 0(%rbp), %rcx /* Reload flags. */
8080+ movq 8(%rbp), %rdi /* Reload raddr. */
8181+ movq 16(%rbp), %rbp /* Reload old frame pointer. */
8282+LUW2:
8383+8484+ /* The first byte of the flags contains the FFI_TYPE. */
8585+ movzbl %cl, %r10d
8686+ leaq Lstore_table(%rip), %r11
8787+ movslq (%r11, %r10, 4), %r10
8888+ addq %r11, %r10
8989+ jmp *%r10
9090+9191+Lstore_table:
9292+ .long Lst_void-Lstore_table /* FFI_TYPE_VOID */
9393+ .long Lst_sint32-Lstore_table /* FFI_TYPE_INT */
9494+ .long Lst_float-Lstore_table /* FFI_TYPE_FLOAT */
9595+ .long Lst_double-Lstore_table /* FFI_TYPE_DOUBLE */
9696+ .long Lst_ldouble-Lstore_table /* FFI_TYPE_LONGDOUBLE */
9797+ .long Lst_uint8-Lstore_table /* FFI_TYPE_UINT8 */
9898+ .long Lst_sint8-Lstore_table /* FFI_TYPE_SINT8 */
9999+ .long Lst_uint16-Lstore_table /* FFI_TYPE_UINT16 */
100100+ .long Lst_sint16-Lstore_table /* FFI_TYPE_SINT16 */
101101+ .long Lst_uint32-Lstore_table /* FFI_TYPE_UINT32 */
102102+ .long Lst_sint32-Lstore_table /* FFI_TYPE_SINT32 */
103103+ .long Lst_int64-Lstore_table /* FFI_TYPE_UINT64 */
104104+ .long Lst_int64-Lstore_table /* FFI_TYPE_SINT64 */
105105+ .long Lst_struct-Lstore_table /* FFI_TYPE_STRUCT */
106106+ .long Lst_int64-Lstore_table /* FFI_TYPE_POINTER */
107107+108108+ .text
109109+ .align 8
110110+Lst_void:
111111+ ret
112112+ .align 8
113113+Lst_uint8:
114114+ movzbq %al, %rax
115115+ movq %rax, (%rdi)
116116+ ret
117117+ .align 8
118118+Lst_sint8:
119119+ movsbq %al, %rax
120120+ movq %rax, (%rdi)
121121+ ret
122122+ .align 8
123123+Lst_uint16:
124124+ movzwq %ax, %rax
125125+ movq %rax, (%rdi)
126126+ .align 8
127127+Lst_sint16:
128128+ movswq %ax, %rax
129129+ movq %rax, (%rdi)
130130+ ret
131131+ .align 8
132132+Lst_uint32:
133133+ movl %eax, %eax
134134+ movq %rax, (%rdi)
135135+ .align 8
136136+Lst_sint32:
137137+ cltq
138138+ movq %rax, (%rdi)
139139+ ret
140140+ .align 8
141141+Lst_int64:
142142+ movq %rax, (%rdi)
143143+ ret
144144+ .align 8
145145+Lst_float:
146146+ movss %xmm0, (%rdi)
147147+ ret
148148+ .align 8
149149+Lst_double:
150150+ movsd %xmm0, (%rdi)
151151+ ret
152152+Lst_ldouble:
153153+ fstpt (%rdi)
154154+ ret
155155+ .align 8
156156+Lst_struct:
157157+ leaq -20(%rsp), %rsi /* Scratch area in redzone. */
158158+159159+ /* We have to locate the values now, and since we don't want to
160160+ write too much data into the user's return value, we spill the
161161+ value to a 16 byte scratch area first. Bits 8, 9, and 10
162162+ control where the values are located. Only one of the three
163163+ bits will be set; see ffi_prep_cif_machdep for the pattern. */
164164+ movd %xmm0, %r10
165165+ movd %xmm1, %r11
166166+ testl $0x100, %ecx
167167+ cmovnz %rax, %rdx
168168+ cmovnz %r10, %rax
169169+ testl $0x200, %ecx
170170+ cmovnz %r10, %rdx
171171+ testl $0x400, %ecx
172172+ cmovnz %r10, %rax
173173+ cmovnz %r11, %rdx
174174+ movq %rax, (%rsi)
175175+ movq %rdx, 8(%rsi)
176176+177177+ /* Bits 12-31 contain the true size of the structure. Copy from
178178+ the scratch area to the true destination. */
179179+ shrl $12, %ecx
180180+ rep movsb
181181+ ret
182182+183183+ /* Many times we can avoid loading any SSE registers at all.
184184+ It's not worth an indirect jump to load the exact set of
185185+ SSE registers needed; zero or all is a good compromise. */
186186+ .align 8
187187+LUW3:
188188+Lload_sse:
189189+ movdqa 48(%r10), %xmm0
190190+ movdqa 64(%r10), %xmm1
191191+ movdqa 80(%r10), %xmm2
192192+ movdqa 96(%r10), %xmm3
193193+ movdqa 112(%r10), %xmm4
194194+ movdqa 128(%r10), %xmm5
195195+ movdqa 144(%r10), %xmm6
196196+ movdqa 160(%r10), %xmm7
197197+ jmp Lret_from_load_sse
198198+199199+LUW4:
200200+ .align 8
201201+ .globl _ffi_closure_unix64
202202+203203+_ffi_closure_unix64:
204204+LUW5:
205205+ /* The carry flag is set by the trampoline iff SSE registers
206206+ are used. Don't clobber it before the branch instruction. */
207207+ leaq -200(%rsp), %rsp
208208+LUW6:
209209+ movq %rdi, (%rsp)
210210+ movq %rsi, 8(%rsp)
211211+ movq %rdx, 16(%rsp)
212212+ movq %rcx, 24(%rsp)
213213+ movq %r8, 32(%rsp)
214214+ movq %r9, 40(%rsp)
215215+ jc Lsave_sse
216216+Lret_from_save_sse:
217217+218218+ movq %r10, %rdi
219219+ leaq 176(%rsp), %rsi
220220+ movq %rsp, %rdx
221221+ leaq 208(%rsp), %rcx
222222+ call _ffi_closure_unix64_inner@PLT
223223+224224+ /* Deallocate stack frame early; return value is now in redzone. */
225225+ addq $200, %rsp
226226+LUW7:
227227+228228+ /* The first byte of the return value contains the FFI_TYPE. */
229229+ movzbl %al, %r10d
230230+ leaq Lload_table(%rip), %r11
231231+ movslq (%r11, %r10, 4), %r10
232232+ addq %r11, %r10
233233+ jmp *%r10
234234+235235+Lload_table:
236236+ .long Lld_void-Lload_table /* FFI_TYPE_VOID */
237237+ .long Lld_int32-Lload_table /* FFI_TYPE_INT */
238238+ .long Lld_float-Lload_table /* FFI_TYPE_FLOAT */
239239+ .long Lld_double-Lload_table /* FFI_TYPE_DOUBLE */
240240+ .long Lld_ldouble-Lload_table /* FFI_TYPE_LONGDOUBLE */
241241+ .long Lld_int8-Lload_table /* FFI_TYPE_UINT8 */
242242+ .long Lld_int8-Lload_table /* FFI_TYPE_SINT8 */
243243+ .long Lld_int16-Lload_table /* FFI_TYPE_UINT16 */
244244+ .long Lld_int16-Lload_table /* FFI_TYPE_SINT16 */
245245+ .long Lld_int32-Lload_table /* FFI_TYPE_UINT32 */
246246+ .long Lld_int32-Lload_table /* FFI_TYPE_SINT32 */
247247+ .long Lld_int64-Lload_table /* FFI_TYPE_UINT64 */
248248+ .long Lld_int64-Lload_table /* FFI_TYPE_SINT64 */
249249+ .long Lld_struct-Lload_table /* FFI_TYPE_STRUCT */
250250+ .long Lld_int64-Lload_table /* FFI_TYPE_POINTER */
251251+252252+ .text
253253+ .align 8
254254+Lld_void:
255255+ ret
256256+ .align 8
257257+Lld_int8:
258258+ movzbl -24(%rsp), %eax
259259+ ret
260260+ .align 8
261261+Lld_int16:
262262+ movzwl -24(%rsp), %eax
263263+ ret
264264+ .align 8
265265+Lld_int32:
266266+ movl -24(%rsp), %eax
267267+ ret
268268+ .align 8
269269+Lld_int64:
270270+ movq -24(%rsp), %rax
271271+ ret
272272+ .align 8
273273+Lld_float:
274274+ movss -24(%rsp), %xmm0
275275+ ret
276276+ .align 8
277277+Lld_double:
278278+ movsd -24(%rsp), %xmm0
279279+ ret
280280+ .align 8
281281+Lld_ldouble:
282282+ fldt -24(%rsp)
283283+ ret
284284+ .align 8
285285+Lld_struct:
286286+ /* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
287287+ %rax/%xmm0, %xmm0/%xmm1. We collapse two by always loading
288288+ both rdx and xmm1 with the second word. For the remaining,
289289+ bit 8 set means xmm0 gets the second word, and bit 9 means
290290+ that rax gets the second word. */
291291+ movq -24(%rsp), %rcx
292292+ movq -16(%rsp), %rdx
293293+ movq -16(%rsp), %xmm1
294294+ testl $0x100, %eax
295295+ cmovnz %rdx, %rcx
296296+ movd %rcx, %xmm0
297297+ testl $0x200, %eax
298298+ movq -24(%rsp), %rax
299299+ cmovnz %rdx, %rax
300300+ ret
301301+302302+ /* See the comment above Lload_sse; the same logic applies here. */
303303+ .align 8
304304+LUW8:
305305+Lsave_sse:
306306+ movdqa %xmm0, 48(%rsp)
307307+ movdqa %xmm1, 64(%rsp)
308308+ movdqa %xmm2, 80(%rsp)
309309+ movdqa %xmm3, 96(%rsp)
310310+ movdqa %xmm4, 112(%rsp)
311311+ movdqa %xmm5, 128(%rsp)
312312+ movdqa %xmm6, 144(%rsp)
313313+ movdqa %xmm7, 160(%rsp)
314314+ jmp Lret_from_save_sse
315315+316316+LUW9:
317317+//.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
318318+.text
319319+EH_frame1:
320320+ .set L$set$0,LECIE1-LSCIE1 /* CIE Length */
321321+ .long L$set$0
322322+LSCIE1:
323323+ .long 0x0 /* CIE Identifier Tag */
324324+ .byte 0x1 /* CIE Version */
325325+ .ascii "zR\0" /* CIE Augmentation */
326326+ .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */
327327+ .byte 0x78 /* sleb128 -8; CIE Data Alignment Factor */
328328+ .byte 0x10 /* CIE RA Column */
329329+ .byte 0x1 /* uleb128 0x1; Augmentation size */
330330+ .byte 0x10 /* FDE Encoding (pcrel sdata4) */
331331+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
332332+ .byte 0x7 /* uleb128 0x7 */
333333+ .byte 0x8 /* uleb128 0x8 */
334334+ .byte 0x90 /* DW_CFA_offset, column 0x10 */
335335+ .byte 0x1
336336+ .align 8
337337+LECIE1:
338338+ .globl _ffi_call_unix64.eh
339339+_ffi_call_unix64.eh:
340340+LSFDE1:
341341+ .set L$set$1,LEFDE1-LASFDE1 /* FDE Length */
342342+ .long L$set$1
343343+LASFDE1:
344344+ .long LASFDE1-EH_frame1 /* FDE CIE offset */
345345+ .quad LUW0-. /* FDE initial location */
346346+ .set L$set$2,LUW4-LUW0 /* FDE address range */
347347+ .quad L$set$2
348348+ .byte 0x0 /* Augmentation size */
349349+ .byte 0x4 /* DW_CFA_advance_loc4 */
350350+ .set L$set$3,LUW1-LUW0
351351+ .long L$set$3
352352+353353+ /* New stack frame based off rbp. This is a itty bit of unwind
354354+ trickery in that the CFA *has* changed. There is no easy way
355355+ to describe it correctly on entry to the function. Fortunately,
356356+ it doesn't matter too much since at all points we can correctly
357357+ unwind back to ffi_call. Note that the location to which we
358358+ moved the return address is (the new) CFA-8, so from the
359359+ perspective of the unwind info, it hasn't moved. */
360360+ .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */
361361+ .byte 0x6
362362+ .byte 0x20
363363+ .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */
364364+ .byte 0x2
365365+ .byte 0xa /* DW_CFA_remember_state */
366366+367367+ .byte 0x4 /* DW_CFA_advance_loc4 */
368368+ .set L$set$4,LUW2-LUW1
369369+ .long L$set$4
370370+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
371371+ .byte 0x7
372372+ .byte 0x8
373373+ .byte 0xc0+6 /* DW_CFA_restore, %rbp */
374374+375375+ .byte 0x4 /* DW_CFA_advance_loc4 */
376376+ .set L$set$5,LUW3-LUW2
377377+ .long L$set$5
378378+ .byte 0xb /* DW_CFA_restore_state */
379379+380380+ .align 8
381381+LEFDE1:
382382+ .globl _ffi_closure_unix64.eh
383383+_ffi_closure_unix64.eh:
384384+LSFDE3:
385385+ .set L$set$6,LEFDE3-LASFDE3 /* FDE Length */
386386+ .long L$set$6
387387+LASFDE3:
388388+ .long LASFDE3-EH_frame1 /* FDE CIE offset */
389389+ .quad LUW5-. /* FDE initial location */
390390+ .set L$set$7,LUW9-LUW5 /* FDE address range */
391391+ .quad L$set$7
392392+ .byte 0x0 /* Augmentation size */
393393+394394+ .byte 0x4 /* DW_CFA_advance_loc4 */
395395+ .set L$set$8,LUW6-LUW5
396396+ .long L$set$8
397397+ .byte 0xe /* DW_CFA_def_cfa_offset */
398398+ .byte 208,1 /* uleb128 208 */
399399+ .byte 0xa /* DW_CFA_remember_state */
400400+401401+ .byte 0x4 /* DW_CFA_advance_loc4 */
402402+ .set L$set$9,LUW7-LUW6
403403+ .long L$set$9
404404+ .byte 0xe /* DW_CFA_def_cfa_offset */
405405+ .byte 0x8
406406+407407+ .byte 0x4 /* DW_CFA_advance_loc4 */
408408+ .set L$set$10,LUW8-LUW7
409409+ .long L$set$10
410410+ .byte 0xb /* DW_CFA_restore_state */
411411+412412+ .align 8
413413+LEFDE3:
414414+ // .subsections_via_symbols
415415+416416+#endif /* __x86_64__ */
+418
src/libffi/x86/x86-darwin.S
···11+#ifdef __i386__
22+/* -----------------------------------------------------------------------
33+ darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc.
44+55+ X86 Foreign Function Interface
66+77+ Permission is hereby granted, free of charge, to any person obtaining
88+ a copy of this software and associated documentation files (the
99+ ``Software''), to deal in the Software without restriction, including
1010+ without limitation the rights to use, copy, modify, merge, publish,
1111+ distribute, sublicense, and/or sell copies of the Software, and to
1212+ permit persons to whom the Software is furnished to do so, subject to
1313+ the following conditions:
1414+1515+ The above copyright notice and this permission notice shall be included
1616+ in all copies or substantial portions of the Software.
1717+1818+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
1919+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2020+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2121+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2222+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2323+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2424+ OTHER DEALINGS IN THE SOFTWARE.
2525+ ----------------------------------------------------------------------- */
2626+2727+/*
2828+ * This file is based on sysv.S and then hacked up by Ronald who hasn't done
2929+ * assembly programming in 8 years.
3030+ */
3131+3232+#ifndef __x86_64__
3333+3434+#define LIBFFI_ASM
3535+#include <fficonfig.h>
3636+#include <ffi.h>
3737+3838+#ifdef PyObjC_STRICT_DEBUGGING
3939+ /* XXX: Debugging of stack alignment, to be removed */
4040+#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0
4141+#else
4242+#define ASSERT_STACK_ALIGNED
4343+#endif
4444+4545+.text
4646+4747+.globl _ffi_prep_args
4848+4949+ .align 16
5050+.globl _ffi_call_SYSV
5151+5252+_ffi_call_SYSV:
5353+LFB1:
5454+ pushl %ebp
5555+LCFI0:
5656+ movl %esp,%ebp
5757+LCFI1:
5858+ subl $8,%esp
5959+ /* Make room for all of the new args. */
6060+ movl 16(%ebp),%ecx
6161+ subl %ecx,%esp
6262+6363+ movl %esp,%eax
6464+6565+ /* Place all of the ffi_prep_args in position */
6666+ subl $8,%esp
6767+ pushl 12(%ebp)
6868+ pushl %eax
6969+ call *8(%ebp)
7070+7171+ /* Return stack to previous state and call the function */
7272+ addl $16,%esp
7373+7474+ call *28(%ebp)
7575+7676+ /* Remove the space we pushed for the args */
7777+ movl 16(%ebp),%ecx
7878+ addl %ecx,%esp
7979+8080+ /* Load %ecx with the return type code */
8181+ movl 20(%ebp),%ecx
8282+8383+ /* If the return value pointer is NULL, assume no return value. */
8484+ cmpl $0,24(%ebp)
8585+ jne Lretint
8686+8787+ /* Even if there is no space for the return value, we are
8888+ obliged to handle floating-point values. */
8989+ cmpl $FFI_TYPE_FLOAT,%ecx
9090+ jne Lnoretval
9191+ fstp %st(0)
9292+9393+ jmp Lepilogue
9494+9595+Lretint:
9696+ cmpl $FFI_TYPE_INT,%ecx
9797+ jne Lretfloat
9898+ /* Load %ecx with the pointer to storage for the return value */
9999+ movl 24(%ebp),%ecx
100100+ movl %eax,0(%ecx)
101101+ jmp Lepilogue
102102+103103+Lretfloat:
104104+ cmpl $FFI_TYPE_FLOAT,%ecx
105105+ jne Lretdouble
106106+ /* Load %ecx with the pointer to storage for the return value */
107107+ movl 24(%ebp),%ecx
108108+ fstps (%ecx)
109109+ jmp Lepilogue
110110+111111+Lretdouble:
112112+ cmpl $FFI_TYPE_DOUBLE,%ecx
113113+ jne Lretlongdouble
114114+ /* Load %ecx with the pointer to storage for the return value */
115115+ movl 24(%ebp),%ecx
116116+ fstpl (%ecx)
117117+ jmp Lepilogue
118118+119119+Lretlongdouble:
120120+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
121121+ jne Lretint64
122122+ /* Load %ecx with the pointer to storage for the return value */
123123+ movl 24(%ebp),%ecx
124124+ fstpt (%ecx)
125125+ jmp Lepilogue
126126+127127+Lretint64:
128128+ cmpl $FFI_TYPE_SINT64,%ecx
129129+ jne Lretstruct1b
130130+ /* Load %ecx with the pointer to storage for the return value */
131131+ movl 24(%ebp),%ecx
132132+ movl %eax,0(%ecx)
133133+ movl %edx,4(%ecx)
134134+ jmp Lepilogue
135135+136136+Lretstruct1b:
137137+ cmpl $FFI_TYPE_SINT8,%ecx
138138+ jne Lretstruct2b
139139+ /* Load %ecx with the pointer to storage for the return value */
140140+ movl 24(%ebp),%ecx
141141+ movb %al,0(%ecx)
142142+ jmp Lepilogue
143143+144144+Lretstruct2b:
145145+ cmpl $FFI_TYPE_SINT16,%ecx
146146+ jne Lretstruct
147147+ /* Load %ecx with the pointer to storage for the return value */
148148+ movl 24(%ebp),%ecx
149149+ movw %ax,0(%ecx)
150150+ jmp Lepilogue
151151+152152+Lretstruct:
153153+ cmpl $FFI_TYPE_STRUCT,%ecx
154154+ jne Lnoretval
155155+ /* Nothing to do! */
156156+ addl $4,%esp
157157+ popl %ebp
158158+ ret
159159+160160+Lnoretval:
161161+Lepilogue:
162162+ addl $8,%esp
163163+ movl %ebp,%esp
164164+ popl %ebp
165165+ ret
166166+LFE1:
167167+.ffi_call_SYSV_end:
168168+169169+ .align 16
170170+FFI_HIDDEN (ffi_closure_SYSV)
171171+.globl _ffi_closure_SYSV
172172+173173+_ffi_closure_SYSV:
174174+LFB2:
175175+ pushl %ebp
176176+LCFI2:
177177+ movl %esp, %ebp
178178+LCFI3:
179179+ subl $56, %esp
180180+ leal -40(%ebp), %edx
181181+ movl %edx, -12(%ebp) /* resp */
182182+ leal 8(%ebp), %edx
183183+ movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
184184+ leal -12(%ebp), %edx
185185+ movl %edx, (%esp) /* &resp */
186186+ movl %ebx, 8(%esp)
187187+LCFI7:
188188+ call L_ffi_closure_SYSV_inner$stub
189189+ movl 8(%esp), %ebx
190190+ movl -12(%ebp), %ecx
191191+ cmpl $FFI_TYPE_INT, %eax
192192+ je Lcls_retint
193193+ cmpl $FFI_TYPE_FLOAT, %eax
194194+ je Lcls_retfloat
195195+ cmpl $FFI_TYPE_DOUBLE, %eax
196196+ je Lcls_retdouble
197197+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
198198+ je Lcls_retldouble
199199+ cmpl $FFI_TYPE_SINT64, %eax
200200+ je Lcls_retllong
201201+ cmpl $FFI_TYPE_SINT8, %eax
202202+ je Lcls_retstruct1
203203+ cmpl $FFI_TYPE_SINT16, %eax
204204+ je Lcls_retstruct2
205205+ cmpl $FFI_TYPE_STRUCT, %eax
206206+ je Lcls_retstruct
207207+Lcls_epilogue:
208208+ movl %ebp, %esp
209209+ popl %ebp
210210+ ret
211211+Lcls_retint:
212212+ movl (%ecx), %eax
213213+ jmp Lcls_epilogue
214214+Lcls_retfloat:
215215+ flds (%ecx)
216216+ jmp Lcls_epilogue
217217+Lcls_retdouble:
218218+ fldl (%ecx)
219219+ jmp Lcls_epilogue
220220+Lcls_retldouble:
221221+ fldt (%ecx)
222222+ jmp Lcls_epilogue
223223+Lcls_retllong:
224224+ movl (%ecx), %eax
225225+ movl 4(%ecx), %edx
226226+ jmp Lcls_epilogue
227227+Lcls_retstruct1:
228228+ movsbl (%ecx), %eax
229229+ jmp Lcls_epilogue
230230+Lcls_retstruct2:
231231+ movswl (%ecx), %eax
232232+ jmp Lcls_epilogue
233233+Lcls_retstruct:
234234+ lea -8(%ebp),%esp
235235+ movl %ebp, %esp
236236+ popl %ebp
237237+ ret $4
238238+LFE2:
239239+240240+#if !FFI_NO_RAW_API
241241+242242+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
243243+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
244244+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
245245+#define CIF_FLAGS_OFFSET 20
246246+247247+ .align 16
248248+FFI_HIDDEN (ffi_closure_raw_SYSV)
249249+.globl _ffi_closure_raw_SYSV
250250+251251+_ffi_closure_raw_SYSV:
252252+LFB3:
253253+ pushl %ebp
254254+LCFI4:
255255+ movl %esp, %ebp
256256+LCFI5:
257257+ pushl %esi
258258+LCFI6:
259259+ subl $36, %esp
260260+ movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
261261+ movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
262262+ movl %edx, 12(%esp) /* user_data */
263263+ leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
264264+ movl %edx, 8(%esp) /* raw_args */
265265+ leal -24(%ebp), %edx
266266+ movl %edx, 4(%esp) /* &res */
267267+ movl %esi, (%esp) /* cif */
268268+ call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
269269+ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
270270+ cmpl $FFI_TYPE_INT, %eax
271271+ je Lrcls_retint
272272+ cmpl $FFI_TYPE_FLOAT, %eax
273273+ je Lrcls_retfloat
274274+ cmpl $FFI_TYPE_DOUBLE, %eax
275275+ je Lrcls_retdouble
276276+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
277277+ je Lrcls_retldouble
278278+ cmpl $FFI_TYPE_SINT64, %eax
279279+ je Lrcls_retllong
280280+Lrcls_epilogue:
281281+ addl $36, %esp
282282+ popl %esi
283283+ popl %ebp
284284+ ret
285285+Lrcls_retint:
286286+ movl -24(%ebp), %eax
287287+ jmp Lrcls_epilogue
288288+Lrcls_retfloat:
289289+ flds -24(%ebp)
290290+ jmp Lrcls_epilogue
291291+Lrcls_retdouble:
292292+ fldl -24(%ebp)
293293+ jmp Lrcls_epilogue
294294+Lrcls_retldouble:
295295+ fldt -24(%ebp)
296296+ jmp Lrcls_epilogue
297297+Lrcls_retllong:
298298+ movl -24(%ebp), %eax
299299+ movl -20(%ebp), %edx
300300+ jmp Lrcls_epilogue
301301+LFE3:
302302+#endif
303303+304304+.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
305305+L_ffi_closure_SYSV_inner$stub:
306306+ .indirect_symbol _ffi_closure_SYSV_inner
307307+ hlt ; hlt ; hlt ; hlt ; hlt
308308+309309+310310+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
311311+EH_frame1:
312312+ .set L$set$0,LECIE1-LSCIE1
313313+ .long L$set$0
314314+LSCIE1:
315315+ .long 0x0
316316+ .byte 0x1
317317+ .ascii "zR\0"
318318+ .byte 0x1
319319+ .byte 0x7c
320320+ .byte 0x8
321321+ .byte 0x1
322322+ .byte 0x10
323323+ .byte 0xc
324324+ .byte 0x5
325325+ .byte 0x4
326326+ .byte 0x88
327327+ .byte 0x1
328328+ .align 4
329329+LECIE1:
330330+.globl _ffi_call_SYSV.eh
331331+_ffi_call_SYSV.eh:
332332+LSFDE1:
333333+ .set L$set$1,LEFDE1-LASFDE1
334334+ .long L$set$1
335335+LASFDE1:
336336+ .long LASFDE1-EH_frame1
337337+ .long LFB1-.
338338+ .set L$set$2,LFE1-LFB1
339339+ .long L$set$2
340340+ .byte 0x0
341341+ .byte 0x4
342342+ .set L$set$3,LCFI0-LFB1
343343+ .long L$set$3
344344+ .byte 0xe
345345+ .byte 0x8
346346+ .byte 0x84
347347+ .byte 0x2
348348+ .byte 0x4
349349+ .set L$set$4,LCFI1-LCFI0
350350+ .long L$set$4
351351+ .byte 0xd
352352+ .byte 0x4
353353+ .align 4
354354+LEFDE1:
355355+.globl _ffi_closure_SYSV.eh
356356+_ffi_closure_SYSV.eh:
357357+LSFDE2:
358358+ .set L$set$5,LEFDE2-LASFDE2
359359+ .long L$set$5
360360+LASFDE2:
361361+ .long LASFDE2-EH_frame1
362362+ .long LFB2-.
363363+ .set L$set$6,LFE2-LFB2
364364+ .long L$set$6
365365+ .byte 0x0
366366+ .byte 0x4
367367+ .set L$set$7,LCFI2-LFB2
368368+ .long L$set$7
369369+ .byte 0xe
370370+ .byte 0x8
371371+ .byte 0x84
372372+ .byte 0x2
373373+ .byte 0x4
374374+ .set L$set$8,LCFI3-LCFI2
375375+ .long L$set$8
376376+ .byte 0xd
377377+ .byte 0x4
378378+ .align 4
379379+LEFDE2:
380380+381381+#if !FFI_NO_RAW_API
382382+383383+.globl _ffi_closure_raw_SYSV.eh
384384+_ffi_closure_raw_SYSV.eh:
385385+LSFDE3:
386386+ .set L$set$10,LEFDE3-LASFDE3
387387+ .long L$set$10
388388+LASFDE3:
389389+ .long LASFDE3-EH_frame1
390390+ .long LFB3-.
391391+ .set L$set$11,LFE3-LFB3
392392+ .long L$set$11
393393+ .byte 0x0
394394+ .byte 0x4
395395+ .set L$set$12,LCFI4-LFB3
396396+ .long L$set$12
397397+ .byte 0xe
398398+ .byte 0x8
399399+ .byte 0x84
400400+ .byte 0x2
401401+ .byte 0x4
402402+ .set L$set$13,LCFI5-LCFI4
403403+ .long L$set$13
404404+ .byte 0xd
405405+ .byte 0x4
406406+ .byte 0x4
407407+ .set L$set$14,LCFI6-LCFI5
408408+ .long L$set$14
409409+ .byte 0x85
410410+ .byte 0x3
411411+ .align 4
412412+LEFDE3:
413413+414414+#endif
415415+416416+#endif /* ifndef __x86_64__ */
417417+418418+#endif /* defined __i386__ */
+646
src/libffi/x86/x86-ffi64.c
···11+#ifdef __x86_64__
22+33+/* -----------------------------------------------------------------------
44+ x86-ffi64.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
55+66+ x86-64 Foreign Function Interface
77+88+ Permission is hereby granted, free of charge, to any person obtaining
99+ a copy of this software and associated documentation files (the
1010+ ``Software''), to deal in the Software without restriction, including
1111+ without limitation the rights to use, copy, modify, merge, publish,
1212+ distribute, sublicense, and/or sell copies of the Software, and to
1313+ permit persons to whom the Software is furnished to do so, subject to
1414+ the following conditions:
1515+1616+ The above copyright notice and this permission notice shall be included
1717+ in all copies or substantial portions of the Software.
1818+1919+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
2020+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2121+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2222+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2323+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2424+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2525+ OTHER DEALINGS IN THE SOFTWARE.
2626+ ----------------------------------------------------------------------- */
2727+2828+#include <ffi.h>
2929+#include <ffi_common.h>
3030+3131+#include <stdlib.h>
3232+#include <stdarg.h>
3333+3434+#define MAX_GPR_REGS 6
3535+#define MAX_SSE_REGS 8
3636+3737+typedef struct RegisterArgs {
3838+ /* Registers for argument passing. */
3939+ UINT64 gpr[MAX_GPR_REGS];
4040+ __int128_t sse[MAX_SSE_REGS];
4141+} RegisterArgs;
4242+4343+extern void
4444+ffi_call_unix64(
4545+ void* args,
4646+ unsigned long bytes,
4747+ unsigned flags,
4848+ void* raddr,
4949+ void (*fnaddr)(),
5050+ unsigned ssecount);
5151+5252+/* All reference to register classes here is identical to the code in
5353+ gcc/config/i386/i386.c. Do *not* change one without the other. */
5454+5555+/* Register class used for passing given 64bit part of the argument.
5656+ These represent classes as documented by the PS ABI, with the exception
5757+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
5858+ use SF or DFmode move instead of DImode to avoid reformating penalties.
5959+6060+ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
6161+ whenever possible (upper half does contain padding). */
6262+enum x86_64_reg_class
6363+{
6464+ X86_64_NO_CLASS,
6565+ X86_64_INTEGER_CLASS,
6666+ X86_64_INTEGERSI_CLASS,
6767+ X86_64_SSE_CLASS,
6868+ X86_64_SSESF_CLASS,
6969+ X86_64_SSEDF_CLASS,
7070+ X86_64_SSEUP_CLASS,
7171+ X86_64_X87_CLASS,
7272+ X86_64_X87UP_CLASS,
7373+ X86_64_COMPLEX_X87_CLASS,
7474+ X86_64_MEMORY_CLASS
7575+};
7676+7777+#define MAX_CLASSES 4
7878+#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
7979+8080+/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
8181+ of this code is to classify each 8bytes of incoming argument by the register
8282+ class and assign registers accordingly. */
8383+8484+/* Return the union class of CLASS1 and CLASS2.
8585+ See the x86-64 PS ABI for details. */
8686+static enum x86_64_reg_class
8787+merge_classes(
8888+ enum x86_64_reg_class class1,
8989+ enum x86_64_reg_class class2)
9090+{
9191+ /* Rule #1: If both classes are equal, this is the resulting class. */
9292+ if (class1 == class2)
9393+ return class1;
9494+9595+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
9696+ the other class. */
9797+ if (class1 == X86_64_NO_CLASS)
9898+ return class2;
9999+100100+ if (class2 == X86_64_NO_CLASS)
101101+ return class1;
102102+103103+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
104104+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
105105+ return X86_64_MEMORY_CLASS;
106106+107107+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
108108+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
109109+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
110110+ return X86_64_INTEGERSI_CLASS;
111111+112112+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
113113+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
114114+ return X86_64_INTEGER_CLASS;
115115+116116+ /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
117117+ MEMORY is used. */
118118+ if (class1 == X86_64_X87_CLASS
119119+ || class1 == X86_64_X87UP_CLASS
120120+ || class1 == X86_64_COMPLEX_X87_CLASS
121121+ || class2 == X86_64_X87_CLASS
122122+ || class2 == X86_64_X87UP_CLASS
123123+ || class2 == X86_64_COMPLEX_X87_CLASS)
124124+ return X86_64_MEMORY_CLASS;
125125+126126+ /* Rule #6: Otherwise class SSE is used. */
127127+ return X86_64_SSE_CLASS;
128128+}
129129+130130+/* Classify the argument of type TYPE and mode MODE.
131131+ CLASSES will be filled by the register class used to pass each word
132132+ of the operand. The number of words is returned. In case the parameter
133133+ should be passed in memory, 0 is returned. As a special case for zero
134134+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
135135+136136+ See the x86-64 PS ABI for details. */
137137+138138+static int
139139+classify_argument(
140140+ ffi_type* type,
141141+ enum x86_64_reg_class classes[],
142142+ size_t byte_offset)
143143+{
144144+ switch (type->type)
145145+ {
146146+ case FFI_TYPE_UINT8:
147147+ case FFI_TYPE_SINT8:
148148+ case FFI_TYPE_UINT16:
149149+ case FFI_TYPE_SINT16:
150150+ case FFI_TYPE_UINT32:
151151+ case FFI_TYPE_SINT32:
152152+ case FFI_TYPE_UINT64:
153153+ case FFI_TYPE_SINT64:
154154+ case FFI_TYPE_POINTER:
155155+ if (byte_offset + type->size <= 4)
156156+ classes[0] = X86_64_INTEGERSI_CLASS;
157157+ else
158158+ classes[0] = X86_64_INTEGER_CLASS;
159159+160160+ return 1;
161161+162162+ case FFI_TYPE_FLOAT:
163163+ if (byte_offset == 0)
164164+ classes[0] = X86_64_SSESF_CLASS;
165165+ else
166166+ classes[0] = X86_64_SSE_CLASS;
167167+168168+ return 1;
169169+170170+ case FFI_TYPE_DOUBLE:
171171+ classes[0] = X86_64_SSEDF_CLASS;
172172+ return 1;
173173+174174+ case FFI_TYPE_LONGDOUBLE:
175175+ classes[0] = X86_64_X87_CLASS;
176176+ classes[1] = X86_64_X87UP_CLASS;
177177+ return 2;
178178+179179+ case FFI_TYPE_STRUCT:
180180+ {
181181+ ffi_type** ptr;
182182+ int i;
183183+ enum x86_64_reg_class subclasses[MAX_CLASSES];
184184+ const int UNITS_PER_WORD = 8;
185185+ int words =
186186+ (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
187187+188188+ /* If the struct is larger than 16 bytes, pass it on the stack. */
189189+ if (type->size > 16)
190190+ return 0;
191191+192192+ for (i = 0; i < words; i++)
193193+ classes[i] = X86_64_NO_CLASS;
194194+195195+ /* Merge the fields of structure. */
196196+ for (ptr = type->elements; *ptr != NULL; ptr++)
197197+ {
198198+ byte_offset = ALIGN(byte_offset, (*ptr)->alignment);
199199+200200+ int num = classify_argument(*ptr, subclasses, byte_offset % 8);
201201+202202+ if (num == 0)
203203+ return 0;
204204+205205+ int pos = byte_offset / 8;
206206+207207+ for (i = 0; i < num; i++)
208208+ {
209209+ classes[i + pos] =
210210+ merge_classes(subclasses[i], classes[i + pos]);
211211+ }
212212+213213+ byte_offset += (*ptr)->size;
214214+ }
215215+216216+ /* Final merger cleanup. */
217217+ for (i = 0; i < words; i++)
218218+ {
219219+ /* If one class is MEMORY, everything should be passed in
220220+ memory. */
221221+ if (classes[i] == X86_64_MEMORY_CLASS)
222222+ return 0;
223223+224224+ /* The X86_64_SSEUP_CLASS should be always preceded by
225225+ X86_64_SSE_CLASS. */
226226+ if (classes[i] == X86_64_SSEUP_CLASS
227227+ && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
228228+ classes[i] = X86_64_SSE_CLASS;
229229+230230+ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
231231+ if (classes[i] == X86_64_X87UP_CLASS
232232+ && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
233233+ classes[i] = X86_64_SSE_CLASS;
234234+ }
235235+236236+ return words;
237237+ }
238238+239239+ default:
240240+ FFI_ASSERT(0);
241241+ }
242242+243243+ return 0; /* Never reached. */
244244+}
245245+246246+/* Examine the argument and return set number of register required in each
247247+ class. Return zero if parameter should be passed in memory, otherwise
248248+ the number of registers. */
249249+static int
250250+examine_argument(
251251+ ffi_type* type,
252252+ enum x86_64_reg_class classes[MAX_CLASSES],
253253+ _Bool in_return,
254254+ int* pngpr,
255255+ int* pnsse)
256256+{
257257+ int n = classify_argument(type, classes, 0);
258258+ int ngpr = 0;
259259+ int nsse = 0;
260260+ int i;
261261+262262+ if (n == 0)
263263+ return 0;
264264+265265+ for (i = 0; i < n; ++i)
266266+ {
267267+ switch (classes[i])
268268+ {
269269+ case X86_64_INTEGER_CLASS:
270270+ case X86_64_INTEGERSI_CLASS:
271271+ ngpr++;
272272+ break;
273273+274274+ case X86_64_SSE_CLASS:
275275+ case X86_64_SSESF_CLASS:
276276+ case X86_64_SSEDF_CLASS:
277277+ nsse++;
278278+ break;
279279+280280+ case X86_64_NO_CLASS:
281281+ case X86_64_SSEUP_CLASS:
282282+ break;
283283+284284+ case X86_64_X87_CLASS:
285285+ case X86_64_X87UP_CLASS:
286286+ case X86_64_COMPLEX_X87_CLASS:
287287+ return in_return != 0;
288288+289289+ default:
290290+ abort();
291291+ }
292292+ }
293293+294294+ *pngpr = ngpr;
295295+ *pnsse = nsse;
296296+297297+ return n;
298298+}
299299+300300+/* Perform machine dependent cif processing. */
301301+ffi_status
302302+ffi_prep_cif_machdep(
303303+ ffi_cif* cif)
304304+{
305305+ int gprcount = 0;
306306+ int ssecount = 0;
307307+ int flags = cif->rtype->type;
308308+ int i, avn, n, ngpr, nsse;
309309+ enum x86_64_reg_class classes[MAX_CLASSES];
310310+ size_t bytes;
311311+312312+ if (flags != FFI_TYPE_VOID)
313313+ {
314314+ n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
315315+316316+ if (n == 0)
317317+ {
318318+ /* The return value is passed in memory. A pointer to that
319319+ memory is the first argument. Allocate a register for it. */
320320+ gprcount++;
321321+322322+ /* We don't have to do anything in asm for the return. */
323323+ flags = FFI_TYPE_VOID;
324324+ }
325325+ else if (flags == FFI_TYPE_STRUCT)
326326+ {
327327+ /* Mark which registers the result appears in. */
328328+ _Bool sse0 = SSE_CLASS_P(classes[0]);
329329+ _Bool sse1 = n == 2 && SSE_CLASS_P(classes[1]);
330330+331331+ if (sse0 && !sse1)
332332+ flags |= 1 << 8;
333333+ else if (!sse0 && sse1)
334334+ flags |= 1 << 9;
335335+ else if (sse0 && sse1)
336336+ flags |= 1 << 10;
337337+338338+ /* Mark the true size of the structure. */
339339+ flags |= cif->rtype->size << 12;
340340+ }
341341+ }
342342+343343+ /* Go over all arguments and determine the way they should be passed.
344344+ If it's in a register and there is space for it, let that be so. If
345345+ not, add it's size to the stack byte count. */
346346+ for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
347347+ {
348348+ if (examine_argument(cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
349349+ || gprcount + ngpr > MAX_GPR_REGS
350350+ || ssecount + nsse > MAX_SSE_REGS)
351351+ {
352352+ long align = cif->arg_types[i]->alignment;
353353+354354+ if (align < 8)
355355+ align = 8;
356356+357357+ bytes = ALIGN(bytes, align);
358358+ bytes += cif->arg_types[i]->size;
359359+ }
360360+ else
361361+ {
362362+ gprcount += ngpr;
363363+ ssecount += nsse;
364364+ }
365365+ }
366366+367367+ if (ssecount)
368368+ flags |= 1 << 11;
369369+370370+ cif->flags = flags;
371371+ cif->bytes = bytes;
372372+373373+ return FFI_OK;
374374+}
375375+376376+void
377377+ffi_call(
378378+ ffi_cif* cif,
379379+ void (*fn)(),
380380+ void* rvalue,
381381+ void** avalue)
382382+{
383383+ enum x86_64_reg_class classes[MAX_CLASSES];
384384+ char* stack;
385385+ char* argp;
386386+ ffi_type** arg_types;
387387+ int gprcount, ssecount, ngpr, nsse, i, avn;
388388+ _Bool ret_in_memory;
389389+ RegisterArgs* reg_args;
390390+391391+ /* Can't call 32-bit mode from 64-bit mode. */
392392+ FFI_ASSERT(cif->abi == FFI_UNIX64);
393393+394394+ /* If the return value is a struct and we don't have a return value
395395+ address then we need to make one. Note the setting of flags to
396396+ VOID above in ffi_prep_cif_machdep. */
397397+ ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
398398+ && (cif->flags & 0xff) == FFI_TYPE_VOID);
399399+400400+ if (rvalue == NULL && ret_in_memory)
401401+ rvalue = alloca (cif->rtype->size);
402402+403403+ /* Allocate the space for the arguments, plus 4 words of temp space. */
404404+ stack = alloca(sizeof(RegisterArgs) + cif->bytes + 4 * 8);
405405+ reg_args = (RegisterArgs*)stack;
406406+ argp = stack + sizeof(RegisterArgs);
407407+408408+ gprcount = ssecount = 0;
409409+410410+ /* If the return value is passed in memory, add the pointer as the
411411+ first integer argument. */
412412+ if (ret_in_memory)
413413+ reg_args->gpr[gprcount++] = (long) rvalue;
414414+415415+ avn = cif->nargs;
416416+ arg_types = cif->arg_types;
417417+418418+ for (i = 0; i < avn; ++i)
419419+ {
420420+ size_t size = arg_types[i]->size;
421421+ int n;
422422+423423+ n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
424424+425425+ if (n == 0
426426+ || gprcount + ngpr > MAX_GPR_REGS
427427+ || ssecount + nsse > MAX_SSE_REGS)
428428+ {
429429+ long align = arg_types[i]->alignment;
430430+431431+ /* Stack arguments are *always* at least 8 byte aligned. */
432432+ if (align < 8)
433433+ align = 8;
434434+435435+ /* Pass this argument in memory. */
436436+ argp = (void *) ALIGN (argp, align);
437437+ memcpy (argp, avalue[i], size);
438438+ argp += size;
439439+ }
440440+ else
441441+ { /* The argument is passed entirely in registers. */
442442+ char *a = (char *) avalue[i];
443443+ SINT64 signExtendedValue = 0;
444444+ int j;
445445+446446+ /* Sign-extend small signed values to fill the entire register. */
447447+ switch (arg_types[i]->type) {
448448+ case FFI_TYPE_SINT8:
449449+ signExtendedValue = (SINT64) *((SINT8 *) avalue[i]);
450450+ a = (char *) &signExtendedValue;
451451+ size = 8;
452452+ break;
453453+ case FFI_TYPE_SINT16:
454454+ signExtendedValue = (SINT64) *((SINT16*) avalue[i]);
455455+ a = (char *) &signExtendedValue;
456456+ size = 8;
457457+ break;
458458+ case FFI_TYPE_SINT32:
459459+ signExtendedValue = (SINT64) *((SINT32*) avalue[i]);
460460+ a = (char *) &signExtendedValue;
461461+ size = 8;
462462+ break;
463463+ default:
464464+ break;
465465+ }
466466+467467+ for (j = 0; j < n; j++, a += 8, size -= 8)
468468+ {
469469+ switch (classes[j])
470470+ {
471471+ case X86_64_INTEGER_CLASS:
472472+ case X86_64_INTEGERSI_CLASS:
473473+ reg_args->gpr[gprcount] = 0;
474474+ memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8);
475475+ gprcount++;
476476+ break;
477477+478478+ case X86_64_SSE_CLASS:
479479+ case X86_64_SSEDF_CLASS:
480480+ reg_args->sse[ssecount++] = *(UINT64 *) a;
481481+ break;
482482+483483+ case X86_64_SSESF_CLASS:
484484+ reg_args->sse[ssecount++] = *(UINT32 *) a;
485485+ break;
486486+487487+ default:
488488+ abort();
489489+ }
490490+ }
491491+ }
492492+ }
493493+494494+ ffi_call_unix64 (stack, cif->bytes + sizeof(RegisterArgs),
495495+ cif->flags, rvalue, fn, ssecount);
496496+}
497497+498498+extern void ffi_closure_unix64(void);
499499+500500+ffi_status
501501+ffi_prep_closure(
502502+ ffi_closure* closure,
503503+ ffi_cif* cif,
504504+ void (*fun)(ffi_cif*, void*, void**, void*),
505505+ void* user_data)
506506+{
507507+ if (cif->abi != FFI_UNIX64)
508508+ return FFI_BAD_ABI;
509509+510510+ volatile unsigned short* tramp =
511511+ (volatile unsigned short*)&closure->tramp[0];
512512+513513+ tramp[0] = 0xbb49; /* mov <code>, %r11 */
514514+ *(void* volatile*)&tramp[1] = ffi_closure_unix64;
515515+ tramp[5] = 0xba49; /* mov <data>, %r10 */
516516+ *(void* volatile*)&tramp[6] = closure;
517517+518518+ /* Set the carry bit if the function uses any sse registers.
519519+ This is clc or stc, together with the first byte of the jmp. */
520520+ tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
521521+ tramp[11] = 0xe3ff; /* jmp *%r11 */
522522+523523+ closure->cif = cif;
524524+ closure->fun = fun;
525525+ closure->user_data = user_data;
526526+527527+ return FFI_OK;
528528+}
529529+530530+int
531531+ffi_closure_unix64_inner(
532532+ ffi_closure* closure,
533533+ void* rvalue,
534534+ RegisterArgs* reg_args,
535535+ char* argp)
536536+{
537537+ ffi_cif* cif = closure->cif;
538538+ void** avalue = alloca(cif->nargs * sizeof(void *));
539539+ ffi_type** arg_types;
540540+ long i, avn;
541541+ int gprcount = 0;
542542+ int ssecount = 0;
543543+ int ngpr, nsse;
544544+ int ret;
545545+546546+ ret = cif->rtype->type;
547547+548548+ if (ret != FFI_TYPE_VOID)
549549+ {
550550+ enum x86_64_reg_class classes[MAX_CLASSES];
551551+ int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
552552+553553+ if (n == 0)
554554+ {
555555+ /* The return value goes in memory. Arrange for the closure
556556+ return value to go directly back to the original caller. */
557557+ rvalue = (void *) reg_args->gpr[gprcount++];
558558+559559+ /* We don't have to do anything in asm for the return. */
560560+ ret = FFI_TYPE_VOID;
561561+ }
562562+ else if (ret == FFI_TYPE_STRUCT && n == 2)
563563+ {
564564+ /* Mark which register the second word of the structure goes in. */
565565+ _Bool sse0 = SSE_CLASS_P (classes[0]);
566566+ _Bool sse1 = SSE_CLASS_P (classes[1]);
567567+568568+ if (!sse0 && sse1)
569569+ ret |= 1 << 8;
570570+ else if (sse0 && !sse1)
571571+ ret |= 1 << 9;
572572+ }
573573+ }
574574+575575+ avn = cif->nargs;
576576+ arg_types = cif->arg_types;
577577+578578+ for (i = 0; i < avn; ++i)
579579+ {
580580+ enum x86_64_reg_class classes[MAX_CLASSES];
581581+ int n;
582582+583583+ n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
584584+585585+ if (n == 0
586586+ || gprcount + ngpr > MAX_GPR_REGS
587587+ || ssecount + nsse > MAX_SSE_REGS)
588588+ {
589589+ long align = arg_types[i]->alignment;
590590+591591+ /* Stack arguments are *always* at least 8 byte aligned. */
592592+ if (align < 8)
593593+ align = 8;
594594+595595+ /* Pass this argument in memory. */
596596+ argp = (void *) ALIGN (argp, align);
597597+ avalue[i] = argp;
598598+ argp += arg_types[i]->size;
599599+ }
600600+601601+#if !defined(X86_DARWIN)
602602+ /* If the argument is in a single register, or two consecutive
603603+ registers, then we can use that address directly. */
604604+ else if (n == 1 || (n == 2 &&
605605+ SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1])))
606606+ {
607607+ // The argument is in a single register.
608608+ if (SSE_CLASS_P (classes[0]))
609609+ {
610610+ avalue[i] = ®_args->sse[ssecount];
611611+ ssecount += n;
612612+ }
613613+ else
614614+ {
615615+ avalue[i] = ®_args->gpr[gprcount];
616616+ gprcount += n;
617617+ }
618618+ }
619619+#endif
620620+621621+ /* Otherwise, allocate space to make them consecutive. */
622622+ else
623623+ {
624624+ char *a = alloca (16);
625625+ int j;
626626+627627+ avalue[i] = a;
628628+629629+ for (j = 0; j < n; j++, a += 8)
630630+ {
631631+ if (SSE_CLASS_P (classes[j]))
632632+ memcpy (a, ®_args->sse[ssecount++], 8);
633633+ else
634634+ memcpy (a, ®_args->gpr[gprcount++], 8);
635635+ }
636636+ }
637637+ }
638638+639639+ /* Invoke the closure. */
640640+ closure->fun (cif, rvalue, avalue, closure->user_data);
641641+642642+ /* Tell assembly how to perform return type promotions. */
643643+ return ret;
644644+}
645645+646646+#endif /* __x86_64__ */
+436
src/libffi/x86/x86-ffi_darwin.c
···11+#ifdef __i386__
22+/* -----------------------------------------------------------------------
33+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc.
44+ Copyright (c) 2002 Ranjit Mathew
55+ Copyright (c) 2002 Bo Thorsen
66+ Copyright (c) 2002 Roger Sayle
77+88+ x86 Foreign Function Interface
99+1010+ Permission is hereby granted, free of charge, to any person obtaining
1111+ a copy of this software and associated documentation files (the
1212+ ``Software''), to deal in the Software without restriction, including
1313+ without limitation the rights to use, copy, modify, merge, publish,
1414+ distribute, sublicense, and/or sell copies of the Software, and to
1515+ permit persons to whom the Software is furnished to do so, subject to
1616+ the following conditions:
1717+1818+ The above copyright notice and this permission notice shall be included
1919+ in all copies or substantial portions of the Software.
2020+2121+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
2222+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2323+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2424+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2525+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2626+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2727+ OTHER DEALINGS IN THE SOFTWARE.
2828+ ----------------------------------------------------------------------- */
2929+3030+#include <ffi.h>
3131+#include <ffi_common.h>
3232+3333+#include <stdlib.h>
3434+3535+/* ffi_prep_args is called by the assembly routine once stack space
3636+ has been allocated for the function's arguments */
3737+3838+void ffi_prep_args(char *stack, extended_cif *ecif)
3939+{
4040+ register unsigned int i;
4141+ register void **p_argv;
4242+ register char *argp;
4343+ register ffi_type **p_arg;
4444+4545+ argp = stack;
4646+4747+ if (ecif->cif->flags == FFI_TYPE_STRUCT)
4848+ {
4949+ *(void **) argp = ecif->rvalue;
5050+ argp += 4;
5151+ }
5252+5353+ p_argv = ecif->avalue;
5454+5555+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
5656+ i != 0;
5757+ i--, p_arg++)
5858+ {
5959+ size_t z;
6060+6161+ /* Align if necessary */
6262+ if ((sizeof(int) - 1) & (unsigned) argp)
6363+ argp = (char *) ALIGN(argp, sizeof(int));
6464+6565+ z = (*p_arg)->size;
6666+ if (z < sizeof(int))
6767+ {
6868+ z = sizeof(int);
6969+ switch ((*p_arg)->type)
7070+ {
7171+ case FFI_TYPE_SINT8:
7272+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
7373+ break;
7474+7575+ case FFI_TYPE_UINT8:
7676+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
7777+ break;
7878+7979+ case FFI_TYPE_SINT16:
8080+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
8181+ break;
8282+8383+ case FFI_TYPE_UINT16:
8484+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
8585+ break;
8686+8787+ case FFI_TYPE_SINT32:
8888+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
8989+ break;
9090+9191+ case FFI_TYPE_UINT32:
9292+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
9393+ break;
9494+9595+ case FFI_TYPE_STRUCT:
9696+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
9797+ break;
9898+9999+ default:
100100+ FFI_ASSERT(0);
101101+ }
102102+ }
103103+ else
104104+ {
105105+ memcpy(argp, *p_argv, z);
106106+ }
107107+ p_argv++;
108108+ argp += z;
109109+ }
110110+111111+ return;
112112+}
113113+114114+/* Perform machine dependent cif processing */
115115+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
116116+{
117117+ /* Set the return type flag */
118118+ switch (cif->rtype->type)
119119+ {
120120+ case FFI_TYPE_VOID:
121121+#ifdef X86
122122+ case FFI_TYPE_STRUCT:
123123+ case FFI_TYPE_UINT8:
124124+ case FFI_TYPE_UINT16:
125125+ case FFI_TYPE_SINT8:
126126+ case FFI_TYPE_SINT16:
127127+#endif
128128+129129+ case FFI_TYPE_SINT64:
130130+ case FFI_TYPE_FLOAT:
131131+ case FFI_TYPE_DOUBLE:
132132+ case FFI_TYPE_LONGDOUBLE:
133133+ cif->flags = (unsigned) cif->rtype->type;
134134+ break;
135135+136136+ case FFI_TYPE_UINT64:
137137+ cif->flags = FFI_TYPE_SINT64;
138138+ break;
139139+140140+#ifndef X86
141141+ case FFI_TYPE_STRUCT:
142142+ if (cif->rtype->size == 1)
143143+ {
144144+ cif->flags = FFI_TYPE_SINT8; /* same as char size */
145145+ }
146146+ else if (cif->rtype->size == 2)
147147+ {
148148+ cif->flags = FFI_TYPE_SINT16; /* same as short size */
149149+ }
150150+ else if (cif->rtype->size == 4)
151151+ {
152152+ cif->flags = FFI_TYPE_INT; /* same as int type */
153153+ }
154154+ else if (cif->rtype->size == 8)
155155+ {
156156+ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
157157+ }
158158+ else
159159+ {
160160+ cif->flags = FFI_TYPE_STRUCT;
161161+ }
162162+ break;
163163+#endif
164164+165165+ default:
166166+ cif->flags = FFI_TYPE_INT;
167167+ break;
168168+ }
169169+170170+#ifdef X86_DARWIN
171171+ cif->bytes = (cif->bytes + 15) & ~0xF;
172172+#endif
173173+174174+ return FFI_OK;
175175+}
176176+177177+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
178178+ unsigned, unsigned, unsigned *, void (*fn)());
179179+180180+#ifdef X86_WIN32
181181+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
182182+ unsigned, unsigned, unsigned *, void (*fn)());
183183+184184+#endif /* X86_WIN32 */
185185+186186+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
187187+{
188188+ extended_cif ecif;
189189+190190+ ecif.cif = cif;
191191+ ecif.avalue = avalue;
192192+193193+ /* If the return value is a struct and we don't have a return */
194194+ /* value address then we need to make one */
195195+196196+ if ((rvalue == NULL) &&
197197+ (cif->flags == FFI_TYPE_STRUCT))
198198+ {
199199+ ecif.rvalue = alloca(cif->rtype->size);
200200+ }
201201+ else
202202+ ecif.rvalue = rvalue;
203203+204204+205205+ switch (cif->abi)
206206+ {
207207+ case FFI_SYSV:
208208+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
209209+ fn);
210210+ break;
211211+#ifdef X86_WIN32
212212+ case FFI_STDCALL:
213213+ ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
214214+ ecif.rvalue, fn);
215215+ break;
216216+#endif /* X86_WIN32 */
217217+ default:
218218+ FFI_ASSERT(0);
219219+ break;
220220+ }
221221+}
222222+223223+224224+/** private members **/
225225+226226+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
227227+ void** args, ffi_cif* cif);
228228+void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
229229+__attribute__ ((regparm(1)));
230230+unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
231231+__attribute__ ((regparm(1)));
232232+void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
233233+__attribute__ ((regparm(1)));
234234+235235+/* This function is jumped to by the trampoline */
236236+237237+unsigned int FFI_HIDDEN
238238+ffi_closure_SYSV_inner (closure, respp, args)
239239+ffi_closure *closure;
240240+void **respp;
241241+void *args;
242242+{
243243+ // our various things...
244244+ ffi_cif *cif;
245245+ void **arg_area;
246246+247247+ cif = closure->cif;
248248+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
249249+250250+ /* this call will initialize ARG_AREA, such that each
251251+ * element in that array points to the corresponding
252252+ * value on the stack; and if the function returns
253253+ * a structure, it will re-set RESP to point to the
254254+ * structure return address. */
255255+256256+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
257257+258258+ (closure->fun) (cif, *respp, arg_area, closure->user_data);
259259+260260+ return cif->flags;
261261+}
262262+263263+static void
264264+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
265265+ ffi_cif *cif)
266266+{
267267+ register unsigned int i;
268268+ register void **p_argv;
269269+ register char *argp;
270270+ register ffi_type **p_arg;
271271+272272+ argp = stack;
273273+274274+ if ( cif->flags == FFI_TYPE_STRUCT ) {
275275+ *rvalue = *(void **) argp;
276276+ argp += 4;
277277+ }
278278+279279+ p_argv = avalue;
280280+281281+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
282282+ {
283283+ size_t z;
284284+285285+ /* Align if necessary */
286286+ if ((sizeof(int) - 1) & (unsigned) argp) {
287287+ argp = (char *) ALIGN(argp, sizeof(int));
288288+ }
289289+290290+ z = (*p_arg)->size;
291291+292292+ /* because we're little endian, this is what it turns into. */
293293+294294+ *p_argv = (void*) argp;
295295+296296+ p_argv++;
297297+ argp += z;
298298+ }
299299+300300+ return;
301301+}
302302+303303+/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
304304+305305+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
306306+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
307307+unsigned int __fun = (unsigned int)(FUN); \
308308+unsigned int __ctx = (unsigned int)(CTX); \
309309+unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \
310310+*(unsigned char*) &__tramp[0] = 0xb8; \
311311+*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
312312+*(unsigned char *) &__tramp[5] = 0xe9; \
313313+*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
314314+})
315315+316316+317317+/* the cif must already be prep'ed */
318318+ffi_status
319319+ffi_prep_closure (ffi_closure* closure,
320320+ ffi_cif* cif,
321321+ void (*fun)(ffi_cif*,void*,void**,void*),
322322+ void *user_data)
323323+{
324324+ if (cif->abi != FFI_SYSV)
325325+ return FFI_BAD_ABI;
326326+327327+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
328328+ &ffi_closure_SYSV, \
329329+ (void*)closure);
330330+331331+ closure->cif = cif;
332332+ closure->user_data = user_data;
333333+ closure->fun = fun;
334334+335335+ return FFI_OK;
336336+}
337337+338338+/* ------- Native raw API support -------------------------------- */
339339+340340+#if !FFI_NO_RAW_API
341341+342342+ffi_status
343343+ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
344344+ ffi_cif* cif,
345345+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
346346+ void *user_data,
347347+ void *codeloc)
348348+{
349349+ int i;
350350+351351+ FFI_ASSERT (cif->abi == FFI_SYSV);
352352+353353+ // we currently don't support certain kinds of arguments for raw
354354+ // closures. This should be implemented by a separate assembly language
355355+ // routine, since it would require argument processing, something we
356356+ // don't do now for performance.
357357+358358+ for (i = cif->nargs-1; i >= 0; i--)
359359+ {
360360+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
361361+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
362362+ }
363363+364364+365365+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
366366+ codeloc);
367367+368368+ closure->cif = cif;
369369+ closure->user_data = user_data;
370370+ closure->fun = fun;
371371+372372+ return FFI_OK;
373373+}
374374+375375+static void
376376+ffi_prep_args_raw(char *stack, extended_cif *ecif)
377377+{
378378+ memcpy (stack, ecif->avalue, ecif->cif->bytes);
379379+}
380380+381381+/* we borrow this routine from libffi (it must be changed, though, to
382382+ * actually call the function passed in the first argument. as of
383383+ * libffi-1.20, this is not the case.)
384384+ */
385385+386386+extern void
387387+ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
388388+ unsigned, unsigned *, void (*fn)());
389389+390390+#ifdef X86_WIN32
391391+extern void
392392+ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
393393+ unsigned, unsigned *, void (*fn)());
394394+#endif /* X86_WIN32 */
395395+396396+void
397397+ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
398398+{
399399+ extended_cif ecif;
400400+ void **avalue = (void **)fake_avalue;
401401+402402+ ecif.cif = cif;
403403+ ecif.avalue = avalue;
404404+405405+ /* If the return value is a struct and we don't have a return */
406406+ /* value address then we need to make one */
407407+408408+ if ((rvalue == NULL) &&
409409+ (cif->rtype->type == FFI_TYPE_STRUCT))
410410+ {
411411+ ecif.rvalue = alloca(cif->rtype->size);
412412+ }
413413+ else
414414+ ecif.rvalue = rvalue;
415415+416416+417417+ switch (cif->abi)
418418+ {
419419+ case FFI_SYSV:
420420+ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
421421+ ecif.rvalue, fn);
422422+ break;
423423+#ifdef X86_WIN32
424424+ case FFI_STDCALL:
425425+ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
426426+ ecif.rvalue, fn);
427427+ break;
428428+#endif /* X86_WIN32 */
429429+ default:
430430+ FFI_ASSERT(0);
431431+ break;
432432+ }
433433+}
434434+435435+#endif
436436+#endif // __i386__
-32
src/libncurses/CMakeLists.txt
···11-project(libncurses)
22-33-cmake_minimum_required(VERSION 2.4.0)
44-if(COMMAND cmake_policy)
55- cmake_policy(SET CMP0003 NEW)
66-endif(COMMAND cmake_policy)
77-88-enable_language(ASM_NASM)
99-1010-#if (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang")
1111-# message(FATAL_ERROR "Clang is the only supported compiler.")
1212-#endif (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang")
1313-1414-#configure_file(config.h.in config.h)
1515-#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fblocks -std=c++0x")
1616-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
1717-1818-set(libncurses_SRCS
1919- wrap.c
2020-)
2121-2222-SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${SUFFIX}/darling")
2323-#SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-new-dtags")
2424-SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
2525-SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
2626-2727-add_library(ncursesdarwin SHARED ${libncurses_SRCS})
2828-# -luuid to make uuid_ functions available for Darwin apps
2929-target_link_libraries(ncursesdarwin -lncurses)
3030-3131-install(TARGETS ncursesdarwin DESTINATION "lib${SUFFIX}/darling")
3232-