Comparar commits
354 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| ff3d76fd42 | |||
| 7e0a412c4f | |||
| 39e6a58604 | |||
| 853cc722a1 | |||
| 3f5023068c | |||
| ebb8e89456 | |||
| a098b44f4c | |||
| 10d1e51393 | |||
| 9bcc884276 | |||
| a044a56b1c | |||
| 59bb61a366 | |||
| f2981454cb | |||
| 39dccddb60 | |||
| 3afaa9a34a | |||
| 65f40c35a2 | |||
| 0a1ab12a8d | |||
| e1539266e6 | |||
| 7c5e60b5f4 | |||
| e72ed5eeaa | |||
| bd78c9c331 | |||
| 84d3253f86 | |||
| 964c5b93f8 | |||
| 6c194233a5 | |||
| 8360bf1cd0 | |||
| d578b89619 | |||
| dee20f8e45 | |||
| 4130e1972d | |||
| 1ff9c604bb | |||
| 211060eb8f | |||
| 78d9c638ba | |||
| afaf338160 | |||
| 9e9c4aeb77 | |||
| 8efc0b1f40 | |||
| 1df51398ae | |||
| cd2277cc79 | |||
| 164e6fe04b | |||
| c365ee7577 | |||
| f22c38bbd9 | |||
| 03e9ee321a | |||
| 95f31151ec | |||
| 198ed1ef85 | |||
| 4f17e1f142 | |||
| ff9454da44 | |||
| ea14ae85e8 | |||
| 52891f8a93 | |||
| c8f1bde8e2 | |||
| 6a6e7f862f | |||
| d52fbed05c | |||
| 322052ce65 | |||
| af18df2bc2 | |||
| 236c939132 | |||
| c411f140f3 | |||
| 3d56106b07 | |||
| 8c01954c50 | |||
| fed646a207 | |||
| d76441cf71 | |||
| ee6696fdf4 | |||
| c6265c36a9 | |||
| cc5e41bf32 | |||
| 049d8386ff | |||
| 3b7efa4e74 | |||
| d992ac54a2 | |||
| 2d3fb36420 | |||
| 30ff28e1d8 | |||
| 09f8f310f4 | |||
| 53d7b16564 | |||
| 18dd85d6cb | |||
| 74ee6ea8b4 | |||
| 2541679dbd | |||
| cbb062cc35 | |||
| 8cf8878425 | |||
| 24b72070c0 | |||
| d72c49e556 | |||
| 3000dc237f | |||
| 1fbf9dc44f | |||
| 90af15ef5c | |||
| 55e4a5aa15 | |||
| a0c80f279b | |||
| 8195e0e11d | |||
| 56b3f8cef0 | |||
| 28a00f61ff | |||
| 7f2ea33a80 | |||
| 92ff23e77f | |||
| 58fb8ca2df | |||
| cc3fbd975c | |||
| e449a43bbe | |||
| 71c792f51b | |||
| 7c7c9f3272 | |||
| ed62e48b95 | |||
| 17d9e9e68d | |||
| 6972a4ffda | |||
| 1833aa0fb9 | |||
| f1fb139b4e | |||
| 5cb470331d | |||
| 269deef6db | |||
| 42695e7250 | |||
| a6e56b97f6 | |||
| 747d6c32d4 | |||
| eab6e41cde | |||
| 69dbe845f4 | |||
| f498318c07 | |||
| 630b9c0ac4 | |||
| 0cad4386fa | |||
| 09cb76f264 | |||
| 2e3a48ccdd | |||
| 5e4814d992 | |||
| 5c0cc6f153 | |||
| 857fe3de46 | |||
| e2214f8adb | |||
| 1106229a57 | |||
| bc9d0be295 | |||
| 3b836249fe | |||
| a26e394061 | |||
| b8099539f0 | |||
| dc411e8f99 | |||
| 404585d134 | |||
| 19ce713188 | |||
| 89284fe55f | |||
| ba022c338a | |||
| 097e5f3924 | |||
| ed2c518d96 | |||
| 0e5843995f | |||
| 5b9cd52784 | |||
| 2db72615b5 | |||
| f6ab3edc23 | |||
| cef6194628 | |||
| 53f387b203 | |||
| 4fbcb5b5fb | |||
| 8e7652ef6a | |||
| 83038cf24a | |||
| b00ff3e98f | |||
| da2773e02a | |||
| 01d71b7bed | |||
| 19afda0069 | |||
| 9e1196444e | |||
| f38364b399 | |||
| 36849e7716 | |||
| b764162526 | |||
| a3d9aa8501 | |||
| c71480eaf8 | |||
| 9af9291b73 | |||
| 68ce0c383e | |||
| 75af086be8 | |||
| 1ac92cca9b | |||
| be72fbab29 | |||
| 70150bdf45 | |||
| 6b452bafae | |||
| 8ddac835b6 | |||
| 69043d0293 | |||
| a82e6c354e | |||
| 84e8de6e9f | |||
| 3aeecc9eb1 | |||
| 00d0b59cd1 | |||
| bda487e870 | |||
| c1d28ba8d5 | |||
| 5feacad4a5 | |||
| 10ea848900 | |||
| d14178be4c | |||
| 3f5b1375ab | |||
| eaf444eabc | |||
| 6309741522 | |||
| 9dc9a293f3 | |||
| f2c2a4fce9 | |||
| c0b69e57d5 | |||
| 59a259f4d3 | |||
| 3de1eb36d3 | |||
| c3813b6d7f | |||
| 8d27f68baa | |||
| ff3cd68b8c | |||
| cadeba6cb5 | |||
| 0739e7dc00 | |||
| edfdfd2e85 | |||
| 7b7a42f221 | |||
| 4b18d1f73d | |||
| c3042afaf3 | |||
| b0304e9679 | |||
| 2e7e03d014 | |||
| aea706c528 | |||
| 0cfe60e9d1 | |||
| 14e2e92e86 | |||
| 884402787b | |||
| 01c78756af | |||
| 7086846465 | |||
| 838d4ad920 | |||
| 7e37eaaf77 | |||
| 07cc7a3719 | |||
| 2b9be16ffa | |||
| 9458d88f67 | |||
| 6a34124175 | |||
| 39c8792ece | |||
| 1d04af52e3 | |||
| 26e9509c9b | |||
| 9c157d3215 | |||
| d22de05b0b | |||
| 1fe3dc7c20 | |||
| f7c0bc613a | |||
| c7fa2da826 | |||
| da11bece0f | |||
| e3399b11ed | |||
| 115ab36fce | |||
| f8c7a245bf | |||
| ce806772f0 | |||
| dcc1f6b4f1 | |||
| 2829f5941a | |||
| cd98813de5 | |||
| e4a91de766 | |||
| 3425a763bc | |||
| 2340e7a777 | |||
| 5cbe2058c1 | |||
| c6dddbd02b | |||
| 5ffc0c3748 | |||
| bd29f83ee9 | |||
| 9474f853f8 | |||
| 0c25275ec2 | |||
| 39228c27ed | |||
| 5e93cc704d | |||
| b509af8959 | |||
| d57e96dc56 | |||
| b01d6d1982 | |||
| 35b6ded138 | |||
| acc46605f2 | |||
| 16d1996ed0 | |||
| 92a515c33e | |||
| e4363160ba | |||
| 1dc2781d2b | |||
| bb27735fe6 | |||
| b2a54c100c | |||
| 25723e7141 | |||
| 70758199c7 | |||
| e8bb12563f | |||
| d66a8e32c3 | |||
| 7c3b7fd6b5 | |||
| 1a2f93a8b3 | |||
| 944c95cf7a | |||
| 00fa972430 | |||
| f5179e6794 | |||
| 80e2b5a749 | |||
| 7063d9996f | |||
| bdfeb13f0d | |||
| 69205de17d | |||
| 260d513fea | |||
| 3704031875 | |||
| 8406f5f48f | |||
| 23a9e73212 | |||
| 429e37d3ad | |||
| 51e79c4283 | |||
| affcab04e2 | |||
| 59689d5522 | |||
| b13c84cf46 | |||
| 265289f679 | |||
| fb5036cd6d | |||
| 40bec108e7 | |||
| b922048fa8 | |||
| affca4b92d | |||
| 3e53d8752e | |||
| 4d92f6c8e7 | |||
| 0e185fa11a | |||
| f73986bd21 | |||
| 0208f68fe5 | |||
| 01adb0e638 | |||
| 1edd456322 | |||
| c9b5428008 | |||
| d5fa5633d5 | |||
| ac35bfc6fc | |||
| f7942975fe | |||
| 59aa6bb1bf | |||
| 45a45ab990 | |||
| 4db74cbea8 | |||
| c3e1101ffa | |||
| 7e0cc12e92 | |||
| 2d7dc885ec | |||
| a0525f03ee | |||
| 2b30dfb314 | |||
| bf41e64840 | |||
| 4d39ddee67 | |||
| d58b032b41 | |||
| 91e5478df6 | |||
| bd0768f877 | |||
| 49d345f767 | |||
| 12ac48fc79 | |||
| 6b91c41da8 | |||
| 2b59579e35 | |||
| 6cbdf3f3a3 | |||
| 1d1dc81104 | |||
| f045a2367f | |||
| 6257f07d1a | |||
| 4232af563c | |||
| 961543615c | |||
| aeb0abab87 | |||
| 77fe243556 | |||
| d4970cf452 | |||
| f0b1462f2d | |||
| 27e52f33ba | |||
| fadab28eb6 | |||
| b5e44c8dfa | |||
| f359848d1a | |||
| c30df49e15 | |||
| 675561bb9a | |||
| abc0bbf381 | |||
| e332366d15 | |||
| d420424039 | |||
| f4932dd020 | |||
| 085520ddc8 | |||
| 77175b3f72 | |||
| 2544e45a0b | |||
| 6002211b1c | |||
| ccabd2b16b | |||
| e680ecfbfc | |||
| e7ba089659 | |||
| 0cd4aa24e2 | |||
| 5826120fbd | |||
| 220aa4b27d | |||
| 1c3adc892c | |||
| 4af66bb62f | |||
| 5435965f90 | |||
| 6fdb7de0fe | |||
| bc7144b01b | |||
| e57279831e | |||
| 7247436b5f | |||
| a8b0d40ff9 | |||
| f893d22733 | |||
| 688ddfeced | |||
| f9e40776d4 | |||
| 8c1d2eb47f | |||
| 1359dfc658 | |||
| 6e2de5eee3 | |||
| 8807355af3 | |||
| f7e9f91ade | |||
| c4860de618 | |||
| c578b58314 | |||
| acdb200512 | |||
| e75be655ce | |||
| d6669a0dd5 | |||
| 4819d52b00 | |||
| 2dbf801eb4 | |||
| d170961701 | |||
| c7747d9769 | |||
| dd2aa9a8de | |||
| 4e9452abed | |||
| 6d3b2bddaf | |||
| ebc6a9c28a | |||
| 78ffc52a8b | |||
| b4d77e827d | |||
| bfb73f08fd | |||
| af8b7f037c | |||
| 334f0b0609 | |||
| 3ab5cb4a1d | |||
| d2a9eb5a8b | |||
| bc75c54bd3 | |||
| d3782ec816 | |||
| 8d8d3843c4 | |||
| 49634f3bf2 | |||
| c64a84c769 | |||
| 9813273b07 |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="contrib/ntservice/src"/>
|
||||
<classpathentry kind="src" path="contrib/platform/src"/>
|
||||
<classpathentry kind="src" path="contrib/x11/src"/>
|
||||
<classpathentry excluding="build*" kind="src" path="contrib/balloontips"/>
|
||||
<classpathentry excluding="build*" kind="src" path="contrib/shapedwindowdemo"/>
|
||||
<classpathentry excluding="build*" kind="src" path="contrib/dnddemo"/>
|
||||
<classpathentry excluding="build*" kind="src" path="contrib/w32keyhook"/>
|
||||
<classpathentry excluding="build*" kind="src" path="contrib/alphamaskdemo"/>
|
||||
<classpathentry excluding="build*" kind="src" path="contrib/balloonmanagerdemo"/>
|
||||
<classpathentry kind="src" output="build.eclipse/test-classes" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
|
||||
<classpathentry kind="output" path="build.eclipse/classes"/>
|
||||
</classpath>
|
||||
+23
-9
@@ -1,9 +1,23 @@
|
||||
build
|
||||
build-d64
|
||||
build.eclipse
|
||||
build.number
|
||||
.metadata
|
||||
bin
|
||||
contrib/ntservice/dist
|
||||
contrib/platform/dist
|
||||
|
||||
.libs
|
||||
.deps
|
||||
*.o
|
||||
*.lo
|
||||
.dirstamp
|
||||
*.la
|
||||
Makefile
|
||||
config.log
|
||||
config.status
|
||||
*~
|
||||
fficonfig.h
|
||||
include/ffi.h
|
||||
include/ffitarget.h
|
||||
libffi.pc
|
||||
libtool
|
||||
stamp-h1
|
||||
libffi*gz
|
||||
autom4te.cache
|
||||
libffi.xcodeproj/xcuserdata
|
||||
libffi.xcodeproj/project.xcworkspace
|
||||
ios/
|
||||
osx/
|
||||
build_*/
|
||||
@@ -0,0 +1 @@
|
||||
2
|
||||
@@ -1,3 +1,256 @@
|
||||
2012-04-02 Peter Bergner <bergner@vnet.ibm.com>
|
||||
|
||||
* src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp.
|
||||
Silence casting pointer to integer of different size warning.
|
||||
Delete goto to previously deleted label.
|
||||
(ffi_call): Silence possibly undefined warning.
|
||||
(ffi_closure_helper_SYSV): Declare variable type.
|
||||
|
||||
2012-03-13 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
|
||||
just return FFI_BAD_ABI when things are wrong.
|
||||
* src/sh64/ffi.c (ffi_prep_closure_loc): Ditto.
|
||||
|
||||
2012-03-09 David Edelsohn <dje.gcc@gmail.com>
|
||||
|
||||
* src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64
|
||||
change to return value of ffi_closure_helper_DARWIN and load type
|
||||
from return type.
|
||||
|
||||
2012-03-03 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* src/x86/ffi64.c (ffi_call): Cast the return value to unsigned
|
||||
long.
|
||||
(ffi_prep_closure_loc): Cast to 64bit address in trampoline.
|
||||
(ffi_closure_unix64_inner): Cast return pointer to unsigned long
|
||||
first.
|
||||
|
||||
* src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32.
|
||||
(ffi_arg): Set to unsigned long long for x32.
|
||||
(ffi_sarg): Set to long long for x32.
|
||||
|
||||
2012-03-03 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI.
|
||||
|
||||
2012-03-03 Andoni Morales Alastruey <ylatuya@gmail.com>
|
||||
|
||||
* configure.ac: Add -no-undefined for both 32- and 64-bit x86
|
||||
windows-like hosts.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2012-02-27 Mikael Pettersson <mikpe@it.uu.se>
|
||||
|
||||
PR libffi/52223
|
||||
* Makefile.am (FLAGS_TO_PASS): Define.
|
||||
* Makefile.in: Regenerate.
|
||||
|
||||
2012-02-23 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* src/*/ffitarget.h: Ensure that users never include ffitarget.h
|
||||
directly.
|
||||
|
||||
2012-02-23 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
PR libffi/52221
|
||||
* src/x86/ffi.c (ffi_closure_raw_THISCALL): New
|
||||
prototype.
|
||||
(ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for
|
||||
thiscall-convention.
|
||||
(ffi_raw_call): Use ffi_prep_args_raw.
|
||||
* src/x86/win32.S (ffi_closure_raw_THISCALL): Add
|
||||
implementation for stub.
|
||||
|
||||
2012-02-10 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
* configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64
|
||||
windows target.
|
||||
* configure: Regenerated.
|
||||
|
||||
2012-02-08 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
* src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32
|
||||
also FFI_THISCALL.
|
||||
* src/x86/ffi.c (ffi_closure_THISCALL): Add prototype.
|
||||
(FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code.
|
||||
(ffi_prep_closure_loc): Add FFI_THISCALL support.
|
||||
* src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size.
|
||||
* src/x86/win32.S (ffi_closure_THISCALL): New closure code
|
||||
for thiscall-calling convention.
|
||||
* testsuite/libffi.call/closure_thiscall.c: New test.
|
||||
|
||||
2012-01-28 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
* src/libffi/src/x86/ffi.c (ffi_call_win32): Add new
|
||||
argument to prototype for specify calling-convention.
|
||||
(ffi_call): Add support for stdcall/thiscall convention.
|
||||
(ffi_prep_args): Likewise.
|
||||
(ffi_raw_call): Likewise.
|
||||
* src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and
|
||||
FFI_FASTCALL.
|
||||
* src/x86/win32.S (_ffi_call_win32): Add support for
|
||||
fastcall/thiscall calling-convention calls.
|
||||
* testsuite/libffi.call/fastthis1_win32.c: New test.
|
||||
* testsuite/libffi.call/fastthis2_win32.c: New test.
|
||||
* testsuite/libffi.call/fastthis3_win32.c: New test.
|
||||
* testsuite/libffi.call/strlen2_win32.c: New test.
|
||||
* testsuite/libffi.call/many2_win32.c: New test.
|
||||
* testsuite/libffi.call/struct1_win32.c: New test.
|
||||
* testsuite/libffi.call/struct2_win32.c: New test.
|
||||
|
||||
2012-01-23 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI.
|
||||
|
||||
2012-01-23 Anthony Green <green@moxielogic.com>
|
||||
Chris Young <cdyoung@ntlworld.com>
|
||||
|
||||
* configure.ac: Add Amiga support.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2012-01-23 Dmitry Nadezhin <dmitry.nadezhin@gmail.com>
|
||||
|
||||
* include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions.
|
||||
|
||||
2012-01-23 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain
|
||||
mc68000. Test for __HAVE_68881__ in addition to __MC68881__.
|
||||
|
||||
2012-01-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/48496
|
||||
* src/ia64/ffi.c (ffi_call): Fix up aliasing violations.
|
||||
|
||||
2012-01-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* configure.ac (i?86-*-*): Set TARGET to X86_64.
|
||||
* configure: Regenerate.
|
||||
|
||||
2011-12-07 Andrew Pinski <apinski@cavium.com>
|
||||
|
||||
PR libffi/50051
|
||||
* src/mips/n32.S: Add ".set mips4".
|
||||
|
||||
2011-11-21 Andreas Tobler <andreast@fgznet.ch>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
||||
2011-11-12 David Gilbert <david.gilbert@linaro.org>
|
||||
|
||||
* doc/libffi.texi, include/ffi.h.in, include/ffi_common.h,
|
||||
man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3,
|
||||
man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h,
|
||||
src/cris/ffi.c, src/prep_cif.c,
|
||||
testsuite/libffi.call/cls_double_va.c,
|
||||
testsuite/libffi.call/cls_longdouble_va.c,
|
||||
testsuite/libffi.call/float_va.c: Many changes to support variadic
|
||||
function calls.
|
||||
|
||||
2011-11-12 Kyle Moffett <Kyle.D.Moffett@boeing.com>
|
||||
|
||||
* src/powerpc/ffi.c, src/powerpc/ffitarget.h,
|
||||
src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for
|
||||
softfloat powerpc variants.
|
||||
|
||||
2011-11-12 Petr Salinger <Petr.Salinger@seznam.cz>
|
||||
|
||||
* configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2011-11-12 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max
|
||||
alignment of 4 for wince on ARM.
|
||||
|
||||
2011-11-12 Kyle Moffett <Kyle.D.Moffett@boeing.com>
|
||||
Anthony Green <green@moxielogic.com>
|
||||
|
||||
* src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string
|
||||
instructions (not available on some cores, like the PPC440).
|
||||
|
||||
2011-11-12 Kimura Wataru <kimuraw@i.nifty.jp>
|
||||
|
||||
* m4/ax_enable_builddir: Change from string comparison to numeric
|
||||
comparison for wc output.
|
||||
* configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS
|
||||
X 10.7.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2011-11-12 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* Makefile.am (AM_CCASFLAGS): Add -g option to build assembly
|
||||
files with debug info.
|
||||
* Makefile.in: Rebuilt.
|
||||
|
||||
2011-11-12 Jasper Lievisse Adriaanse <jasper@openbsd.org>
|
||||
|
||||
* README: Update list of supported OpenBSD systems.
|
||||
|
||||
2011-11-12 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* libtool-version: Update.
|
||||
* Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if
|
||||
FFI_DEBUG.
|
||||
(libffi_la_SOURCES): Remove src/debug.c
|
||||
(EXTRA_DIST): Add src/debug.c
|
||||
* Makefile.in: Rebuilt.
|
||||
* README: Update for 3.0.11.
|
||||
|
||||
2011-11-10 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check.
|
||||
* configure, aclocal.m4: Rebuild.
|
||||
|
||||
2011-09-04 Iain Sandoe <iains@gcc.gnu.org>
|
||||
|
||||
PR libffi/49594
|
||||
* src/powerpc/darwin_closure.S (stubs): Make the stub binding
|
||||
helper reference track the architecture pointer size.
|
||||
|
||||
2011-08-25 Andrew Haley <aph@redhat.com>
|
||||
|
||||
* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly
|
||||
instructions.
|
||||
* src/arm/sysv.S (ffi_arm_trampoline): Put them here instead.
|
||||
|
||||
2011-07-11 Andrew Haley <aph@redhat.com>
|
||||
|
||||
* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache.
|
||||
|
||||
2011-06-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* testsuite/libffi.call/cls_double_va.c: Move PR number to comment.
|
||||
* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
|
||||
|
||||
2011-06-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR libffi/46660
|
||||
* testsuite/libffi.call/cls_double_va.c: xfail dg-output on
|
||||
mips-sgi-irix6*.
|
||||
* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
|
||||
|
||||
2011-06-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8,
|
||||
PRId8 instead of %hhu, %hhd.
|
||||
* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8,
|
||||
PRIu8): Define.
|
||||
[__sgi__] (PRId8, PRIu8): Define.
|
||||
|
||||
2011-04-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE):
|
||||
Define.
|
||||
Use them to handle ELF vs. ECOFF differences.
|
||||
[__osf__] (_GLOBAL__F_ffi_call_osf): Define.
|
||||
|
||||
2011-03-30 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* src/powerpc/darwin.S: Fix unknown FDE encoding.
|
||||
* src/powerpc/darwin_closure.S: ditto.
|
||||
|
||||
2011-02-25 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more
|
||||
@@ -8,6 +261,10 @@
|
||||
* m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2011-02-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
||||
2011-02-13 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* include/ffi_common.h (UNLIKELY, LIKELY): Define.
|
||||
@@ -25,20 +282,15 @@
|
||||
* src/ia64/ffi.c (ffi_prep_closure_loc): Ditto.
|
||||
* src/avr32/ffi.c (ffi_prep_closure_loc): Ditto.
|
||||
|
||||
2011-02-11 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* libtool-version: Update.
|
||||
* Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if
|
||||
FFI_DEBUG.
|
||||
(libffi_la_SOURCES): Remove src/debug.c
|
||||
(EXTRA_DIST): Add src/debug.c
|
||||
* Makefile.in: Rebuilt.
|
||||
|
||||
2011-02-11 Anthony Green <green@moxielogic.com>
|
||||
|
||||
* src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
|
||||
just return FFI_BAD_ABI when things are wrong.
|
||||
|
||||
2012-02-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* src/sparc/v9.S (STACKFRAME): Bump to 176.
|
||||
|
||||
2011-02-09 Stuart Shelton <srcshelton@gmail.com>
|
||||
|
||||
http://bugs.gentoo.org/show_bug.cgi?id=286911
|
||||
@@ -99,11 +351,8 @@
|
||||
2011-02-08 Ginn Chen <ginn.chen@oracle.com>
|
||||
|
||||
* src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio
|
||||
aggregate return ABI.
|
||||
|
||||
2011-02-08 Ed <ed@kdtc.net>
|
||||
|
||||
* src/powerpc/asm.h: Fix grammar nit in comment.
|
||||
aggregate return ABI. Flush cache.
|
||||
(ffi_prep_closure_loc): Flush cache.
|
||||
|
||||
2011-02-11 Anthony Green <green@moxielogic.com>
|
||||
|
||||
@@ -114,14 +363,25 @@
|
||||
instructions.
|
||||
* src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN.
|
||||
|
||||
2011-02-08 Ed <ed@kdtc.net>
|
||||
|
||||
* src/powerpc/asm.h: Fix grammar nit in comment.
|
||||
|
||||
2011-02-08 Uli Link <ul.mcamafia@linkitup.de>
|
||||
|
||||
* include/ffi.h.in (FFI_64_BIT_MAX): Define and use.
|
||||
|
||||
2011-02-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR libffi/46661
|
||||
* testsuite/libffi.call/cls_pointer.c (main): Cast void * to
|
||||
uintptr_t first.
|
||||
* testsuite/libffi.call/cls_pointer_stack.c (main): Likewise.
|
||||
|
||||
2011-02-08 Rafael Avila de Espindola <respindola@mozilla.com>
|
||||
|
||||
* configure.ac: Fix x86 test for pc related relocs.
|
||||
* confifure: Rebuilt.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2011-02-07 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
@@ -559,6 +819,13 @@
|
||||
* src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE
|
||||
type on HP-UX.
|
||||
|
||||
2012-02-13 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
PR libffi/52221
|
||||
* src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall
|
||||
support for X86_WIN32.
|
||||
(FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement.
|
||||
|
||||
2009-12-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long
|
||||
@@ -733,6 +1000,11 @@
|
||||
* man/Makefile.in: Regenerate.
|
||||
* testsuite/Makefile.in: Regenerate.
|
||||
|
||||
2011-08-22 Jasper Lievisse Adriaanse <jasper@openbsd.org>
|
||||
|
||||
* configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2009-07-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
|
||||
* configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force.
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,457 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
libffi @VERSION@ - Copyright (c) 2011 Anthony Green
|
||||
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the ``Software''), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
The basic API is described in the README file.
|
||||
|
||||
The raw API is designed to bypass some of the argument packing
|
||||
and unpacking on architectures for which it can be avoided.
|
||||
|
||||
The closure API allows interpreted functions to be packaged up
|
||||
inside a C function pointer, so that they can be called as C functions,
|
||||
with no understanding on the client side that they are interpreted.
|
||||
It can also be used in other cases in which it is necessary to package
|
||||
up a user specified parameter and a function pointer as a single
|
||||
function pointer.
|
||||
|
||||
The closure API must be implemented in order to get its functionality,
|
||||
e.g. for use by gij. Routines are provided to emulate the raw API
|
||||
if the underlying platform doesn't allow faster implementation.
|
||||
|
||||
More details on the raw and cloure API can be found in:
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
|
||||
|
||||
and
|
||||
|
||||
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
|
||||
-------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#define LIBFFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
#ifndef @TARGET@
|
||||
#define @TARGET@
|
||||
#endif
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
#include <ffitarget.h>
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
|
||||
But we can find it either under the correct ANSI name, or under GNU
|
||||
C's internal name. */
|
||||
|
||||
#define FFI_64_BIT_MAX 9223372036854775807
|
||||
|
||||
#ifdef LONG_LONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
# endif
|
||||
# endif /* __PPC64__ */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The closure code assumes that this works on pointers, i.e. a size_t */
|
||||
/* can hold a pointer. */
|
||||
|
||||
typedef struct _ffi_type
|
||||
{
|
||||
size_t size;
|
||||
unsigned short alignment;
|
||||
unsigned short type;
|
||||
struct _ffi_type **elements;
|
||||
} ffi_type;
|
||||
|
||||
#ifndef LIBFFI_HIDE_BASIC_TYPES
|
||||
#if SCHAR_MAX == 127
|
||||
# define ffi_type_uchar ffi_type_uint8
|
||||
# define ffi_type_schar ffi_type_sint8
|
||||
#else
|
||||
#error "char size not supported"
|
||||
#endif
|
||||
|
||||
#if SHRT_MAX == 32767
|
||||
# define ffi_type_ushort ffi_type_uint16
|
||||
# define ffi_type_sshort ffi_type_sint16
|
||||
#elif SHRT_MAX == 2147483647
|
||||
# define ffi_type_ushort ffi_type_uint32
|
||||
# define ffi_type_sshort ffi_type_sint32
|
||||
#else
|
||||
#error "short size not supported"
|
||||
#endif
|
||||
|
||||
#if INT_MAX == 32767
|
||||
# define ffi_type_uint ffi_type_uint16
|
||||
# define ffi_type_sint ffi_type_sint16
|
||||
#elif INT_MAX == 2147483647
|
||||
# define ffi_type_uint ffi_type_uint32
|
||||
# define ffi_type_sint ffi_type_sint32
|
||||
#elif INT_MAX == 9223372036854775807
|
||||
# define ffi_type_uint ffi_type_uint64
|
||||
# define ffi_type_sint ffi_type_sint64
|
||||
#else
|
||||
#error "int size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "no 64-bit data type supported"
|
||||
# endif
|
||||
#elif LONG_MAX != FFI_64_BIT_MAX
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define ffi_type_ulong ffi_type_uint32
|
||||
# define ffi_type_slong ffi_type_sint32
|
||||
#elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define ffi_type_ulong ffi_type_uint64
|
||||
# define ffi_type_slong ffi_type_sint64
|
||||
#else
|
||||
#error "long size not supported"
|
||||
#endif
|
||||
|
||||
/* Need minimal decorations for DLLs to works on Windows. */
|
||||
/* GCC has autoimport and autoexport. Rely on Libtool to */
|
||||
/* help MSVC export from a DLL, but always declare data */
|
||||
/* to be imported for MSVC clients. This costs an extra */
|
||||
/* indirection for MSVC clients using the static version */
|
||||
/* of the library, but don't worry about that. Besides, */
|
||||
/* as a workaround, they can define FFI_BUILDING if they */
|
||||
/* *know* they are going to link with the static library. */
|
||||
#if defined _MSC_VER && !defined FFI_BUILDING
|
||||
#define FFI_EXTERN extern __declspec(dllimport)
|
||||
#else
|
||||
#define FFI_EXTERN extern
|
||||
#endif
|
||||
|
||||
/* These are defined in types.c */
|
||||
FFI_EXTERN ffi_type ffi_type_void;
|
||||
FFI_EXTERN ffi_type ffi_type_uint8;
|
||||
FFI_EXTERN ffi_type ffi_type_sint8;
|
||||
FFI_EXTERN ffi_type ffi_type_uint16;
|
||||
FFI_EXTERN ffi_type ffi_type_sint16;
|
||||
FFI_EXTERN ffi_type ffi_type_uint32;
|
||||
FFI_EXTERN ffi_type ffi_type_sint32;
|
||||
FFI_EXTERN ffi_type ffi_type_uint64;
|
||||
FFI_EXTERN ffi_type ffi_type_sint64;
|
||||
FFI_EXTERN ffi_type ffi_type_float;
|
||||
FFI_EXTERN ffi_type ffi_type_double;
|
||||
FFI_EXTERN ffi_type ffi_type_pointer;
|
||||
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
FFI_EXTERN ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
#endif
|
||||
#endif /* LIBFFI_HIDE_BASIC_TYPES */
|
||||
|
||||
typedef enum {
|
||||
FFI_OK = 0,
|
||||
FFI_BAD_TYPEDEF,
|
||||
FFI_BAD_ABI
|
||||
} ffi_status;
|
||||
|
||||
typedef unsigned FFI_TYPE;
|
||||
|
||||
typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* Used internally, but overridden by some architectures */
|
||||
ffi_status ffi_prep_cif_core(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int isvariadic,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
# if LONG_MAX == 2147483647
|
||||
# define FFI_SIZEOF_ARG 4
|
||||
# elif LONG_MAX == FFI_64_BIT_MAX
|
||||
# define FFI_SIZEOF_ARG 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FFI_SIZEOF_JAVA_RAW
|
||||
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
ffi_sarg sint;
|
||||
ffi_arg uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_ARG];
|
||||
void* ptr;
|
||||
} ffi_raw;
|
||||
|
||||
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
|
||||
/* This is a special case for mips64/n32 ABI (and perhaps others) where
|
||||
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
|
||||
typedef union {
|
||||
signed int sint;
|
||||
unsigned int uint;
|
||||
float flt;
|
||||
char data[FFI_SIZEOF_JAVA_RAW];
|
||||
void* ptr;
|
||||
} ffi_java_raw;
|
||||
#else
|
||||
typedef ffi_raw ffi_java_raw;
|
||||
#endif
|
||||
|
||||
|
||||
void ffi_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_raw *avalue);
|
||||
|
||||
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
|
||||
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
|
||||
size_t ffi_raw_size (ffi_cif *cif);
|
||||
|
||||
/* This is analogous to the raw API, except it uses Java parameter */
|
||||
/* packing, even on 64-bit machines. I.e. on 64-bit machines */
|
||||
/* longs and doubles are followed by an empty 64-bit word. */
|
||||
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
|
||||
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
|
||||
size_t ffi_java_raw_size (ffi_cif *cif);
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
ffi_cif *cif;
|
||||
void (*fun)(ffi_cif*,void*,void**,void*);
|
||||
void *user_data;
|
||||
#ifdef __GNUC__
|
||||
} ffi_closure __attribute__((aligned (8)));
|
||||
#else
|
||||
} ffi_closure;
|
||||
# ifdef __sgi
|
||||
# pragma pack 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void *ffi_closure_alloc (size_t size, void **code);
|
||||
void ffi_closure_free (void *);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void*codeloc);
|
||||
|
||||
#ifdef __sgi
|
||||
# pragma pack 8
|
||||
#endif
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* if this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_raw_closure;
|
||||
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
|
||||
ffi_cif *cif;
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
|
||||
/* if this is enabled, then a raw closure has the same layout
|
||||
as a regular closure. We use this to install an intermediate
|
||||
handler to do the transaltion, void** -> ffi_raw*. */
|
||||
|
||||
void (*translate_args)(ffi_cif*,void*,void**,void*);
|
||||
void *this_closure;
|
||||
|
||||
#endif
|
||||
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
|
||||
void *user_data;
|
||||
|
||||
} ffi_java_raw_closure;
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data);
|
||||
|
||||
ffi_status
|
||||
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
/* ---- Public interface definition -------------------------------------- */
|
||||
|
||||
ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
|
||||
/* Useful for eliminating compiler warnings */
|
||||
#define FFI_FN(f) ((void (*)(void))f)
|
||||
|
||||
/* ---- Definitions shared with assembly code ---------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
/* If these change, update src/mips/ffitarget.h. */
|
||||
#define FFI_TYPE_VOID 0
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if @HAVE_LONG_DOUBLE@
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
#define FFI_TYPE_UINT8 5
|
||||
#define FFI_TYPE_SINT8 6
|
||||
#define FFI_TYPE_UINT16 7
|
||||
#define FFI_TYPE_SINT16 8
|
||||
#define FFI_TYPE_UINT32 9
|
||||
#define FFI_TYPE_SINT32 10
|
||||
#define FFI_TYPE_UINT64 11
|
||||
#define FFI_TYPE_SINT64 12
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks) */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_POINTER
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,505 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
#ifdef __USER_LABEL_PREFIX__
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
#else
|
||||
#define CNAME(x) x
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#define ENTRY(x) .globl CNAME(x); CNAME(x):
|
||||
#else
|
||||
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
|
||||
#endif /* __APPLE__ */
|
||||
#endif
|
||||
|
||||
#ifdef __ELF__
|
||||
#define LSYM(x) .x
|
||||
#else
|
||||
#define LSYM(x) x
|
||||
#endif
|
||||
|
||||
/* Use the SOFTFP return value ABI on Mac OS X, as per the iOS ABI
|
||||
Function Call Guide */
|
||||
#ifdef __APPLE__
|
||||
#define __SOFTFP__
|
||||
#endif
|
||||
|
||||
/* We need a better way of testing for this, but for now, this is all
|
||||
we can do. */
|
||||
@ This selects the minimum architecture level required.
|
||||
#define __ARM_ARCH__ 3
|
||||
|
||||
#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 4
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5TEJ__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 5
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|
||||
|| defined(__ARM_ARCH_6M__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 6
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|
||||
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|
||||
|| defined(__ARM_ARCH_7EM__)
|
||||
# undef __ARM_ARCH__
|
||||
# define __ARM_ARCH__ 7
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__ >= 5
|
||||
# define call_reg(x) blx x
|
||||
#elif defined (__ARM_ARCH_4T__)
|
||||
# define call_reg(x) mov lr, pc ; bx x
|
||||
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
|
||||
# define __INTERWORKING__
|
||||
# endif
|
||||
#else
|
||||
# define call_reg(x) mov lr, pc ; mov pc, x
|
||||
#endif
|
||||
|
||||
/* Conditionally compile unwinder directives. */
|
||||
#ifdef __ARM_EABI__
|
||||
#define UNWIND
|
||||
#else
|
||||
#define UNWIND @
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.thumb
|
||||
.thumb_func
|
||||
#ifdef __APPLE__
|
||||
ENTRY($0)
|
||||
#else
|
||||
ENTRY(\name)
|
||||
#endif
|
||||
bx pc
|
||||
nop
|
||||
.arm
|
||||
UNWIND .fnstart
|
||||
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
|
||||
directly from other local arm routines. */
|
||||
#ifdef __APPLE__
|
||||
_L__$0:
|
||||
#else
|
||||
_L__\name:
|
||||
#endif
|
||||
.endm
|
||||
#else
|
||||
.macro ARM_FUNC_START name
|
||||
.text
|
||||
.align 0
|
||||
.arm
|
||||
#ifdef __APPLE__
|
||||
ENTRY($0)
|
||||
#else
|
||||
ENTRY(\name)
|
||||
#endif
|
||||
UNWIND .fnstart
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.macro RETLDM regs=, cond=, dirn=ia
|
||||
#if defined (__INTERWORKING__)
|
||||
.ifc "\regs",""
|
||||
ldr\cond lr, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, lr}
|
||||
.endif
|
||||
bx\cond lr
|
||||
#else
|
||||
.ifc "\regs",""
|
||||
ldr\cond pc, [sp], #4
|
||||
.else
|
||||
ldm\cond\dirn sp!, {\regs, pc}
|
||||
.endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
@ r0: ffi_prep_args
|
||||
@ r1: &ecif
|
||||
@ r2: cif->bytes
|
||||
@ r3: fig->flags
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
@ This assumes we are using gas.
|
||||
ARM_FUNC_START ffi_call_SYSV
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
mov fp, sp
|
||||
|
||||
UNWIND .setfp fp, sp
|
||||
|
||||
@ Make room for all of the new args.
|
||||
sub sp, fp, r2
|
||||
|
||||
@ Place all of the ffi_prep_args in position
|
||||
mov r0, sp
|
||||
@ r1 already set
|
||||
|
||||
@ Call ffi_prep_args(stack, &ecif)
|
||||
bl ffi_prep_args
|
||||
|
||||
@ move first 4 parameters in registers
|
||||
ldmia sp, {r0-r3}
|
||||
|
||||
@ and adjust stack
|
||||
sub lr, fp, sp @ cif->bytes == fp - sp
|
||||
ldr ip, [fp] @ load fn() in advance
|
||||
cmp lr, #16
|
||||
movhs lr, #16
|
||||
add sp, sp, lr
|
||||
|
||||
@ call (fn) (...)
|
||||
call_reg(ip)
|
||||
|
||||
@ Remove the space we pushed for the args
|
||||
mov sp, fp
|
||||
|
||||
@ Load r2 with the pointer to storage for the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL, assume no return value.
|
||||
cmp r2, #0
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return INT
|
||||
cmp r3, #FFI_TYPE_INT
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
cmpne r3, #FFI_TYPE_FLOAT
|
||||
#endif
|
||||
streq r0, [r2]
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return INT64
|
||||
cmp r3, #FFI_TYPE_SINT64
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
cmpne r3, #FFI_TYPE_DOUBLE
|
||||
#endif
|
||||
stmeqia r2, {r0, r1}
|
||||
|
||||
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return FLOAT
|
||||
cmp r3, #FFI_TYPE_FLOAT
|
||||
stfeqs f0, [r2]
|
||||
beq LSYM(Lepilogue)
|
||||
|
||||
@ return DOUBLE or LONGDOUBLE
|
||||
cmp r3, #FFI_TYPE_DOUBLE
|
||||
stfeqd f0, [r2]
|
||||
#endif
|
||||
|
||||
LSYM(Lepilogue):
|
||||
#if defined (__INTERWORKING__)
|
||||
ldmia sp!, {r0-r3,fp, lr}
|
||||
bx lr
|
||||
#else
|
||||
ldmia sp!, {r0-r3,fp, pc}
|
||||
#endif
|
||||
|
||||
.ffi_call_SYSV_end:
|
||||
UNWIND .fnend
|
||||
#ifdef __ELF__
|
||||
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
unsigned int FFI_HIDDEN
|
||||
ffi_closure_SYSV_inner (closure, respp, args)
|
||||
ffi_closure *closure;
|
||||
void **respp;
|
||||
void *args;
|
||||
*/
|
||||
|
||||
ARM_FUNC_START ffi_closure_SYSV
|
||||
UNWIND .pad #16
|
||||
add ip, sp, #16
|
||||
stmfd sp!, {ip, lr}
|
||||
UNWIND .save {r0, lr}
|
||||
add r2, sp, #8
|
||||
UNWIND .pad #16
|
||||
sub sp, sp, #16
|
||||
str sp, [sp, #8]
|
||||
add r1, sp, #8
|
||||
bl CNAME(ffi_closure_SYSV_inner)
|
||||
cmp r0, #FFI_TYPE_INT
|
||||
beq .Lretint
|
||||
|
||||
cmp r0, #FFI_TYPE_FLOAT
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
beq .Lretint
|
||||
#else
|
||||
beq .Lretfloat
|
||||
#endif
|
||||
|
||||
cmp r0, #FFI_TYPE_DOUBLE
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
beq .Lretlonglong
|
||||
#else
|
||||
beq .Lretdouble
|
||||
#endif
|
||||
|
||||
cmp r0, #FFI_TYPE_LONGDOUBLE
|
||||
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
|
||||
beq .Lretlonglong
|
||||
#else
|
||||
beq .Lretlongdouble
|
||||
#endif
|
||||
|
||||
cmp r0, #FFI_TYPE_SINT64
|
||||
beq .Lretlonglong
|
||||
.Lclosure_epilogue:
|
||||
add sp, sp, #16
|
||||
ldmfd sp, {sp, pc}
|
||||
.Lretint:
|
||||
ldr r0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
.Lretlonglong:
|
||||
ldr r0, [sp]
|
||||
ldr r1, [sp, #4]
|
||||
b .Lclosure_epilogue
|
||||
|
||||
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
|
||||
.Lretfloat:
|
||||
ldfs f0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
.Lretdouble:
|
||||
ldfd f0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
.Lretlongdouble:
|
||||
ldfd f0, [sp]
|
||||
b .Lclosure_epilogue
|
||||
#endif
|
||||
|
||||
.ffi_closure_SYSV_end:
|
||||
UNWIND .fnend
|
||||
#ifdef __ELF__
|
||||
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
|
||||
#endif
|
||||
|
||||
|
||||
/* Below are VFP hard-float ABI call and closure implementations.
|
||||
Add VFP FPU directive here. This is only compiled into the library
|
||||
under EABI. */
|
||||
#ifdef __ARM_EABI__
|
||||
.fpu vfp
|
||||
|
||||
@ r0: fn
|
||||
@ r1: &ecif
|
||||
@ r2: cif->bytes
|
||||
@ r3: fig->flags
|
||||
@ sp+0: ecif.rvalue
|
||||
|
||||
ARM_FUNC_START ffi_call_VFP
|
||||
@ Save registers
|
||||
stmfd sp!, {r0-r3, fp, lr}
|
||||
UNWIND .save {r0-r3, fp, lr}
|
||||
mov fp, sp
|
||||
UNWIND .setfp fp, sp
|
||||
|
||||
@ Make room for all of the new args.
|
||||
sub sp, sp, r2
|
||||
|
||||
@ Make room for loading VFP args
|
||||
sub sp, sp, #64
|
||||
|
||||
@ Place all of the ffi_prep_args in position
|
||||
mov r0, sp
|
||||
@ r1 already set
|
||||
sub r2, fp, #64 @ VFP scratch space
|
||||
|
||||
@ Call ffi_prep_args(stack, &ecif, vfp_space)
|
||||
bl ffi_prep_args
|
||||
|
||||
@ Load VFP register args if needed
|
||||
cmp r0, #0
|
||||
beq LSYM(Lbase_args)
|
||||
|
||||
@ Load only d0 if possible
|
||||
cmp r0, #3
|
||||
sub ip, fp, #64
|
||||
flddle d0, [ip]
|
||||
fldmiadgt ip, {d0-d7}
|
||||
|
||||
LSYM(Lbase_args):
|
||||
@ move first 4 parameters in registers
|
||||
ldmia sp, {r0-r3}
|
||||
|
||||
@ and adjust stack
|
||||
sub lr, ip, sp @ cif->bytes == (fp - 64) - sp
|
||||
ldr ip, [fp] @ load fn() in advance
|
||||
cmp lr, #16
|
||||
movhs lr, #16
|
||||
add sp, sp, lr
|
||||
|
||||
@ call (fn) (...)
|
||||
call_reg(ip)
|
||||
|
||||
@ Remove the space we pushed for the args
|
||||
mov sp, fp
|
||||
|
||||
@ Load r2 with the pointer to storage for
|
||||
@ the return value
|
||||
ldr r2, [sp, #24]
|
||||
|
||||
@ Load r3 with the return type code
|
||||
ldr r3, [sp, #12]
|
||||
|
||||
@ If the return value pointer is NULL,
|
||||
@ assume no return value.
|
||||
cmp r2, #0
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_INT
|
||||
streq r0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_SINT64
|
||||
stmeqia r2, {r0, r1}
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_FLOAT
|
||||
fstseq s0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_DOUBLE
|
||||
fstdeq d0, [r2]
|
||||
beq LSYM(Lepilogue_vfp)
|
||||
|
||||
cmp r3, #FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
cmpne r3, #FFI_TYPE_STRUCT_VFP_DOUBLE
|
||||
fstmiadeq r2, {d0-d3}
|
||||
|
||||
LSYM(Lepilogue_vfp):
|
||||
RETLDM "r0-r3,fp"
|
||||
|
||||
.ffi_call_VFP_end:
|
||||
UNWIND .fnend
|
||||
.size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
|
||||
|
||||
|
||||
ARM_FUNC_START ffi_closure_VFP
|
||||
fstmfdd sp!, {d0-d7}
|
||||
@ r0-r3, then d0-d7
|
||||
UNWIND .pad #80
|
||||
add ip, sp, #80
|
||||
stmfd sp!, {ip, lr}
|
||||
UNWIND .save {r0, lr}
|
||||
add r2, sp, #72
|
||||
add r3, sp, #8
|
||||
UNWIND .pad #72
|
||||
sub sp, sp, #72
|
||||
str sp, [sp, #64]
|
||||
add r1, sp, #64
|
||||
bl ffi_closure_SYSV_inner
|
||||
|
||||
cmp r0, #FFI_TYPE_INT
|
||||
beq .Lretint_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_FLOAT
|
||||
beq .Lretfloat_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_DOUBLE
|
||||
cmpne r0, #FFI_TYPE_LONGDOUBLE
|
||||
beq .Lretdouble_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_SINT64
|
||||
beq .Lretlonglong_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_STRUCT_VFP_FLOAT
|
||||
beq .Lretfloat_struct_vfp
|
||||
|
||||
cmp r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
|
||||
beq .Lretdouble_struct_vfp
|
||||
|
||||
.Lclosure_epilogue_vfp:
|
||||
add sp, sp, #72
|
||||
ldmfd sp, {sp, pc}
|
||||
|
||||
.Lretfloat_vfp:
|
||||
flds s0, [sp]
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretdouble_vfp:
|
||||
fldd d0, [sp]
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretint_vfp:
|
||||
ldr r0, [sp]
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretlonglong_vfp:
|
||||
ldmia sp, {r0, r1}
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretfloat_struct_vfp:
|
||||
fldmiad sp, {d0-d1}
|
||||
b .Lclosure_epilogue_vfp
|
||||
.Lretdouble_struct_vfp:
|
||||
fldmiad sp, {d0-d3}
|
||||
b .Lclosure_epilogue_vfp
|
||||
|
||||
.ffi_closure_VFP_end:
|
||||
UNWIND .fnend
|
||||
.size CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
|
||||
#endif
|
||||
|
||||
ENTRY(ffi_arm_trampoline)
|
||||
stmfd sp!, {r0-r3}
|
||||
ldr r0, [pc]
|
||||
ldr pc, [pc]
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
@@ -0,0 +1,841 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
|
||||
Copyright (c) 2002 Ranjit Mathew
|
||||
Copyright (c) 2002 Bo Thorsen
|
||||
Copyright (c) 2002 Roger Sayle
|
||||
Copyright (C) 2008, 2010 Free Software Foundation, Inc.
|
||||
|
||||
x86 Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#if !defined(__x86_64__) || defined(_WIN64)
|
||||
|
||||
#ifdef _WIN64
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments */
|
||||
|
||||
void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
register unsigned int i;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
#ifdef X86_WIN32
|
||||
size_t p_stack_args[2];
|
||||
void *p_stack_data[2];
|
||||
char *argp2 = stack;
|
||||
int stack_args_count = 0;
|
||||
int cabi = ecif->cif->abi;
|
||||
#endif
|
||||
|
||||
argp = stack;
|
||||
|
||||
if ((ecif->cif->flags == FFI_TYPE_STRUCT
|
||||
|| ecif->cif->flags == FFI_TYPE_MS_STRUCT)
|
||||
#ifdef X86_WIN64
|
||||
&& (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
|
||||
&& ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
*(void **) argp = ecif->rvalue;
|
||||
#ifdef X86_WIN32
|
||||
/* For fastcall/thiscall this is first register-passed
|
||||
argument. */
|
||||
if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
|
||||
{
|
||||
p_stack_args[stack_args_count] = sizeof (void*);
|
||||
p_stack_data[stack_args_count] = argp;
|
||||
++stack_args_count;
|
||||
}
|
||||
#endif
|
||||
argp += sizeof(void*);
|
||||
}
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
i != 0;
|
||||
i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
/* Align if necessary */
|
||||
if ((sizeof(void*) - 1) & (size_t) argp)
|
||||
argp = (char *) ALIGN(argp, sizeof(void*));
|
||||
|
||||
z = (*p_arg)->size;
|
||||
#ifdef X86_WIN64
|
||||
if (z > sizeof(ffi_arg)
|
||||
|| ((*p_arg)->type == FFI_TYPE_STRUCT
|
||||
&& (z != 1 && z != 2 && z != 4 && z != 8))
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
|| ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
z = sizeof(ffi_arg);
|
||||
*(void **)argp = *p_argv;
|
||||
}
|
||||
else if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
{
|
||||
memcpy(argp, *p_argv, z);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (z < sizeof(ffi_arg))
|
||||
{
|
||||
z = sizeof(ffi_arg);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT32:
|
||||
*(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT32:
|
||||
*(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
*(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(argp, *p_argv, z);
|
||||
}
|
||||
|
||||
#ifdef X86_WIN32
|
||||
/* For thiscall/fastcall convention register-passed arguments
|
||||
are the first two none-floating-point arguments with a size
|
||||
smaller or equal to sizeof (void*). */
|
||||
if ((cabi == FFI_THISCALL && stack_args_count < 1)
|
||||
|| (cabi == FFI_FASTCALL && stack_args_count < 2))
|
||||
{
|
||||
if (z <= 4
|
||||
&& ((*p_arg)->type != FFI_TYPE_FLOAT
|
||||
&& (*p_arg)->type != FFI_TYPE_STRUCT))
|
||||
{
|
||||
p_stack_args[stack_args_count] = z;
|
||||
p_stack_data[stack_args_count] = argp;
|
||||
++stack_args_count;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
p_argv++;
|
||||
#ifdef X86_WIN64
|
||||
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
|
||||
#else
|
||||
argp += z;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef X86_WIN32
|
||||
/* We need to move the register-passed arguments for thiscall/fastcall
|
||||
on top of stack, so that those can be moved to registers ecx/edx by
|
||||
call-handler. */
|
||||
if (stack_args_count > 0)
|
||||
{
|
||||
size_t zz = (p_stack_args[0] + 3) & ~3;
|
||||
char *h;
|
||||
|
||||
/* Move first argument to top-stack position. */
|
||||
if (p_stack_data[0] != argp2)
|
||||
{
|
||||
h = alloca (zz + 1);
|
||||
memcpy (h, p_stack_data[0], zz);
|
||||
memmove (argp2 + zz, argp2,
|
||||
(size_t) ((char *) p_stack_data[0] - (char*)argp2));
|
||||
memcpy (argp2, h, zz);
|
||||
}
|
||||
|
||||
argp2 += zz;
|
||||
--stack_args_count;
|
||||
if (zz > 4)
|
||||
stack_args_count = 0;
|
||||
|
||||
/* If we have a second argument, then move it on top
|
||||
after the first one. */
|
||||
if (stack_args_count > 0 && p_stack_data[1] != argp2)
|
||||
{
|
||||
zz = p_stack_args[1];
|
||||
zz = (zz + 3) & ~3;
|
||||
h = alloca (zz + 1);
|
||||
h = alloca (zz + 1);
|
||||
memcpy (h, p_stack_data[1], zz);
|
||||
memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2));
|
||||
memcpy (argp2, h, zz);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
unsigned int i;
|
||||
ffi_type **ptr;
|
||||
|
||||
/* Set the return type flag */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
#ifdef X86_WIN64
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
#endif
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#ifndef X86_WIN64
|
||||
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
#endif
|
||||
cif->flags = (unsigned) cif->rtype->type;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT64:
|
||||
#ifdef X86_WIN64
|
||||
case FFI_TYPE_POINTER:
|
||||
#endif
|
||||
cif->flags = FFI_TYPE_SINT64;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
#ifndef X86
|
||||
if (cif->rtype->size == 1)
|
||||
{
|
||||
cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
|
||||
}
|
||||
else if (cif->rtype->size == 2)
|
||||
{
|
||||
cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
|
||||
}
|
||||
else if (cif->rtype->size == 4)
|
||||
{
|
||||
#ifdef X86_WIN64
|
||||
cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
|
||||
#else
|
||||
cif->flags = FFI_TYPE_INT; /* same as int type */
|
||||
#endif
|
||||
}
|
||||
else if (cif->rtype->size == 8)
|
||||
{
|
||||
cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (cif->abi == FFI_MS_CDECL)
|
||||
cif->flags = FFI_TYPE_MS_STRUCT;
|
||||
else
|
||||
cif->flags = FFI_TYPE_STRUCT;
|
||||
/* allocate space for return value pointer */
|
||||
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef X86_WIN64
|
||||
cif->flags = FFI_TYPE_SINT64;
|
||||
break;
|
||||
case FFI_TYPE_INT:
|
||||
cif->flags = FFI_TYPE_SINT32;
|
||||
#else
|
||||
cif->flags = FFI_TYPE_INT;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
|
||||
{
|
||||
if (((*ptr)->alignment - 1) & cif->bytes)
|
||||
cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
|
||||
cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
|
||||
}
|
||||
|
||||
#ifdef X86_WIN64
|
||||
/* ensure space for storing four registers */
|
||||
cif->bytes += 4 * sizeof(ffi_arg);
|
||||
#endif
|
||||
|
||||
#ifdef X86_DARWIN
|
||||
cif->bytes = (cif->bytes + 15) & ~0xF;
|
||||
#endif
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
#ifdef X86_WIN64
|
||||
extern int
|
||||
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
#elif defined(X86_WIN32)
|
||||
extern void
|
||||
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
#else
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
#endif
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
#ifdef X86_WIN64
|
||||
if (rvalue == NULL
|
||||
&& cif->flags == FFI_TYPE_STRUCT
|
||||
&& cif->rtype->size != 1 && cif->rtype->size != 2
|
||||
&& cif->rtype->size != 4 && cif->rtype->size != 8)
|
||||
{
|
||||
ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
|
||||
}
|
||||
#else
|
||||
if (rvalue == NULL
|
||||
&& (cif->flags == FFI_TYPE_STRUCT
|
||||
|| cif->flags == FFI_TYPE_MS_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
#ifdef X86_WIN64
|
||||
case FFI_WIN64:
|
||||
ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
break;
|
||||
#elif defined(X86_WIN32)
|
||||
case FFI_SYSV:
|
||||
case FFI_STDCALL:
|
||||
case FFI_MS_CDECL:
|
||||
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
case FFI_THISCALL:
|
||||
case FFI_FASTCALL:
|
||||
{
|
||||
unsigned int abi = cif->abi;
|
||||
unsigned int i, passed_regs = 0;
|
||||
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
++passed_regs;
|
||||
|
||||
for (i=0; i < cif->nargs && passed_regs < 2;i++)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|
||||
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
|
||||
continue;
|
||||
sz = (cif->arg_types[i]->size + 3) & ~3;
|
||||
if (sz == 0 || sz > 4)
|
||||
continue;
|
||||
++passed_regs;
|
||||
}
|
||||
if (passed_regs < 2 && abi == FFI_FASTCALL)
|
||||
abi = FFI_THISCALL;
|
||||
if (passed_regs < 1 && abi == FFI_THISCALL)
|
||||
abi = FFI_STDCALL;
|
||||
ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
|
||||
fn);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** private members **/
|
||||
|
||||
/* The following __attribute__((regparm(1))) decorations will have no effect
|
||||
on MSVC - standard cdecl convention applies. */
|
||||
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
|
||||
void** args, ffi_cif* cif);
|
||||
void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
|
||||
__attribute__ ((regparm(1)));
|
||||
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
#ifdef X86_WIN32
|
||||
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
#endif
|
||||
#ifdef X86_WIN64
|
||||
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
|
||||
#endif
|
||||
|
||||
/* This function is jumped to by the trampoline */
|
||||
|
||||
#ifdef X86_WIN64
|
||||
void * FFI_HIDDEN
|
||||
ffi_closure_win64_inner (ffi_closure *closure, void *args) {
|
||||
ffi_cif *cif;
|
||||
void **arg_area;
|
||||
void *result;
|
||||
void *resp = &result;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will change RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
|
||||
|
||||
(closure->fun) (cif, resp, arg_area, closure->user_data);
|
||||
|
||||
/* The result is returned in rax. This does the right thing for
|
||||
result types except for floats; we have to 'mov xmm0, rax' in the
|
||||
caller to correct this.
|
||||
TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
|
||||
*/
|
||||
return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
|
||||
}
|
||||
|
||||
#else
|
||||
unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
|
||||
ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
|
||||
{
|
||||
/* our various things... */
|
||||
ffi_cif *cif;
|
||||
void **arg_area;
|
||||
|
||||
cif = closure->cif;
|
||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
||||
|
||||
/* this call will initialize ARG_AREA, such that each
|
||||
* element in that array points to the corresponding
|
||||
* value on the stack; and if the function returns
|
||||
* a structure, it will change RESP to point to the
|
||||
* structure return address. */
|
||||
|
||||
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
|
||||
|
||||
(closure->fun) (cif, *respp, arg_area, closure->user_data);
|
||||
|
||||
return cif->flags;
|
||||
}
|
||||
#endif /* !X86_WIN64 */
|
||||
|
||||
static void
|
||||
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
||||
ffi_cif *cif)
|
||||
{
|
||||
register unsigned int i;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
|
||||
argp = stack;
|
||||
|
||||
#ifdef X86_WIN64
|
||||
if (cif->rtype->size > sizeof(ffi_arg)
|
||||
|| (cif->flags == FFI_TYPE_STRUCT
|
||||
&& (cif->rtype->size != 1 && cif->rtype->size != 2
|
||||
&& cif->rtype->size != 4 && cif->rtype->size != 8))) {
|
||||
*rvalue = *(void **) argp;
|
||||
argp += sizeof(void *);
|
||||
}
|
||||
#else
|
||||
if ( cif->flags == FFI_TYPE_STRUCT
|
||||
|| cif->flags == FFI_TYPE_MS_STRUCT ) {
|
||||
*rvalue = *(void **) argp;
|
||||
argp += sizeof(void *);
|
||||
}
|
||||
#endif
|
||||
|
||||
p_argv = avalue;
|
||||
|
||||
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
/* Align if necessary */
|
||||
if ((sizeof(void*) - 1) & (size_t) argp) {
|
||||
argp = (char *) ALIGN(argp, sizeof(void*));
|
||||
}
|
||||
|
||||
#ifdef X86_WIN64
|
||||
if ((*p_arg)->size > sizeof(ffi_arg)
|
||||
|| ((*p_arg)->type == FFI_TYPE_STRUCT
|
||||
&& ((*p_arg)->size != 1 && (*p_arg)->size != 2
|
||||
&& (*p_arg)->size != 4 && (*p_arg)->size != 8)))
|
||||
{
|
||||
z = sizeof(void *);
|
||||
*p_argv = *(void **)argp;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
z = (*p_arg)->size;
|
||||
|
||||
/* because we're little endian, this is what it turns into. */
|
||||
|
||||
*p_argv = (void*) argp;
|
||||
}
|
||||
|
||||
p_argv++;
|
||||
#ifdef X86_WIN64
|
||||
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
|
||||
#else
|
||||
argp += z;
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
void* __fun = (void*)(FUN); \
|
||||
void* __ctx = (void*)(CTX); \
|
||||
*(unsigned char*) &__tramp[0] = 0x41; \
|
||||
*(unsigned char*) &__tramp[1] = 0xbb; \
|
||||
*(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
|
||||
*(unsigned char*) &__tramp[6] = 0x48; \
|
||||
*(unsigned char*) &__tramp[7] = 0xb8; \
|
||||
*(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
|
||||
*(unsigned char *) &__tramp[16] = 0x49; \
|
||||
*(unsigned char *) &__tramp[17] = 0xba; \
|
||||
*(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
|
||||
*(unsigned char *) &__tramp[26] = 0x41; \
|
||||
*(unsigned char *) &__tramp[27] = 0xff; \
|
||||
*(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
|
||||
}
|
||||
|
||||
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned int __dis = __fun - (__ctx + 10); \
|
||||
*(unsigned char*) &__tramp[0] = 0xb8; \
|
||||
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
|
||||
*(unsigned char *) &__tramp[5] = 0xe9; \
|
||||
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
|
||||
}
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned int __dis = __fun - (__ctx + 49); \
|
||||
unsigned short __size = (unsigned short)(SIZE); \
|
||||
*(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
|
||||
*(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
|
||||
*(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
|
||||
*(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
|
||||
*(unsigned char*) &__tramp[13] = 0xb8; \
|
||||
*(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
|
||||
*(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
|
||||
*(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
|
||||
*(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
|
||||
*(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
|
||||
*(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
|
||||
*(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
|
||||
*(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
|
||||
*(unsigned char*) &__tramp[39] = 0xb8; \
|
||||
*(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
|
||||
*(unsigned char *) &__tramp[44] = 0xe8; \
|
||||
*(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
|
||||
*(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
|
||||
*(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
|
||||
}
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned int __dis = __fun - (__ctx + 10); \
|
||||
unsigned short __size = (unsigned short)(SIZE); \
|
||||
*(unsigned char*) &__tramp[0] = 0xb8; \
|
||||
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
|
||||
*(unsigned char *) &__tramp[5] = 0xe8; \
|
||||
*(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
|
||||
*(unsigned char *) &__tramp[10] = 0xc2; \
|
||||
*(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
|
||||
}
|
||||
|
||||
/* the cif must already be prep'ed */
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
#ifdef X86_WIN64
|
||||
#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
|
||||
#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
|
||||
if (cif->abi == FFI_WIN64)
|
||||
{
|
||||
int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
|
||||
FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
|
||||
&ffi_closure_win64,
|
||||
codeloc, mask);
|
||||
/* make sure we can execute here */
|
||||
}
|
||||
#else
|
||||
if (cif->abi == FFI_SYSV)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
|
||||
&ffi_closure_SYSV,
|
||||
(void*)codeloc);
|
||||
}
|
||||
#ifdef X86_WIN32
|
||||
else if (cif->abi == FFI_THISCALL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
|
||||
&ffi_closure_THISCALL,
|
||||
(void*)codeloc,
|
||||
cif->bytes);
|
||||
}
|
||||
else if (cif->abi == FFI_STDCALL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
|
||||
&ffi_closure_STDCALL,
|
||||
(void*)codeloc, cif->bytes);
|
||||
}
|
||||
else if (cif->abi == FFI_MS_CDECL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
|
||||
&ffi_closure_SYSV,
|
||||
(void*)codeloc);
|
||||
}
|
||||
#endif /* X86_WIN32 */
|
||||
#endif /* !X86_WIN64 */
|
||||
else
|
||||
{
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* ------- Native raw API support -------------------------------- */
|
||||
|
||||
#if !FFI_NO_RAW_API
|
||||
|
||||
ffi_status
|
||||
ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cif->abi != FFI_SYSV) {
|
||||
#ifdef X86_WIN32
|
||||
if (cif->abi != FFI_THISCALL)
|
||||
#endif
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
/* we currently don't support certain kinds of arguments for raw
|
||||
closures. This should be implemented by a separate assembly
|
||||
language routine, since it would require argument processing,
|
||||
something we don't do now for performance. */
|
||||
|
||||
for (i = cif->nargs-1; i >= 0; i--)
|
||||
{
|
||||
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
|
||||
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
|
||||
}
|
||||
|
||||
#ifdef X86_WIN32
|
||||
if (cif->abi == FFI_SYSV)
|
||||
{
|
||||
#endif
|
||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
|
||||
codeloc);
|
||||
#ifdef X86_WIN32
|
||||
}
|
||||
else if (cif->abi == FFI_THISCALL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL,
|
||||
codeloc, cif->bytes);
|
||||
}
|
||||
#endif
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ffi_prep_args_raw(char *stack, extended_cif *ecif)
|
||||
{
|
||||
memcpy (stack, ecif->avalue, ecif->cif->bytes);
|
||||
}
|
||||
|
||||
/* we borrow this routine from libffi (it must be changed, though, to
|
||||
* actually call the function passed in the first argument. as of
|
||||
* libffi-1.20, this is not the case.)
|
||||
*/
|
||||
|
||||
void
|
||||
ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
void **avalue = (void **)fake_avalue;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if (rvalue == NULL
|
||||
&& (cif->flags == FFI_TYPE_STRUCT
|
||||
|| cif->flags == FFI_TYPE_MS_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
#ifdef X86_WIN32
|
||||
case FFI_SYSV:
|
||||
case FFI_STDCALL:
|
||||
case FFI_MS_CDECL:
|
||||
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
case FFI_THISCALL:
|
||||
case FFI_FASTCALL:
|
||||
{
|
||||
unsigned int abi = cif->abi;
|
||||
unsigned int i, passed_regs = 0;
|
||||
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
++passed_regs;
|
||||
|
||||
for (i=0; i < cif->nargs && passed_regs < 2;i++)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|
||||
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
|
||||
continue;
|
||||
sz = (cif->arg_types[i]->size + 3) & ~3;
|
||||
if (sz == 0 || sz > 4)
|
||||
continue;
|
||||
++passed_regs;
|
||||
}
|
||||
if (passed_regs < 2 && abi == FFI_FASTCALL)
|
||||
cif->abi = abi = FFI_THISCALL;
|
||||
if (passed_regs < 1 && abi == FFI_THISCALL)
|
||||
cif->abi = abi = FFI_STDCALL;
|
||||
ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !__x86_64__ || X86_WIN64 */
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
stand-alone
|
||||
aix-fix
|
||||
mint
|
||||
win32
|
||||
win32_tests
|
||||
vararg_float_test_fix
|
||||
vfp-eabi
|
||||
msvc-changes
|
||||
win32-return-sign
|
||||
apple-fixes
|
||||
dist-tests
|
||||
icc128
|
||||
x32libtool
|
||||
arm-test-fix
|
||||
xcode
|
||||
darwin-missing-semi
|
||||
xcode-improvements
|
||||
update-disty
|
||||
v3_0_11
|
||||
+6
-1
@@ -6,6 +6,7 @@
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-output "" { xfail avr32*-*-* } } */
|
||||
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
|
||||
/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
@@ -36,7 +37,8 @@ int main (void)
|
||||
arg_types[1] = &ffi_type_double;
|
||||
arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
|
||||
/* This printf call is variadic */
|
||||
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
|
||||
arg_types) == FFI_OK);
|
||||
|
||||
args[0] = &format;
|
||||
@@ -48,6 +50,9 @@ int main (void)
|
||||
printf("res: %d\n", (int) res);
|
||||
// { dg-output "\nres: 4" }
|
||||
|
||||
/* The call to cls_double_va_fn is static, so have to use a normal prep_cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK);
|
||||
|
||||
res = ((int(*)(char*, double))(code))(format, doubleArg);
|
||||
+7
-1
@@ -6,6 +6,7 @@
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
|
||||
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
|
||||
/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
@@ -36,7 +37,8 @@ int main (void)
|
||||
arg_types[1] = &ffi_type_longdouble;
|
||||
arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
|
||||
/* This printf call is variadic */
|
||||
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
|
||||
arg_types) == FFI_OK);
|
||||
|
||||
args[0] = &format;
|
||||
@@ -48,6 +50,10 @@ int main (void)
|
||||
printf("res: %d\n", (int) res);
|
||||
// { dg-output "\nres: 4" }
|
||||
|
||||
/* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
|
||||
arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK);
|
||||
|
||||
res = ((int(*)(char*, long double))(code))(format, ldArg);
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -37,9 +37,9 @@ target_triplet = @target@
|
||||
subdir = testsuite
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
|
||||
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
|
||||
$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
|
||||
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
|
||||
$(top_srcdir)/m4/ax_configure_args.m4 \
|
||||
$(top_srcdir)/m4/ax_enable_builddir.m4 \
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -427,7 +427,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
/* If the return value is passed in memory, add the pointer as the
|
||||
first integer argument. */
|
||||
if (ret_in_memory)
|
||||
reg_args->gpr[gprcount++] = (long) rvalue;
|
||||
reg_args->gpr[gprcount++] = (unsigned long) rvalue;
|
||||
|
||||
avn = cif->nargs;
|
||||
arg_types = cif->arg_types;
|
||||
@@ -509,9 +509,11 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
tramp = (volatile unsigned short *) &closure->tramp[0];
|
||||
|
||||
tramp[0] = 0xbb49; /* mov <code>, %r11 */
|
||||
*(void * volatile *) &tramp[1] = ffi_closure_unix64;
|
||||
*((unsigned long long * volatile) &tramp[1])
|
||||
= (unsigned long) ffi_closure_unix64;
|
||||
tramp[5] = 0xba49; /* mov <data>, %r10 */
|
||||
*(void * volatile *) &tramp[6] = codeloc;
|
||||
*((unsigned long long * volatile) &tramp[6])
|
||||
= (unsigned long) codeloc;
|
||||
|
||||
/* Set the carry bit iff the function uses any sse registers.
|
||||
This is clc or stc, together with the first byte of the jmp. */
|
||||
@@ -550,7 +552,7 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
|
||||
{
|
||||
/* The return value goes in memory. Arrange for the closure
|
||||
return value to go directly back to the original caller. */
|
||||
rvalue = (void *) reg_args->gpr[gprcount++];
|
||||
rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++];
|
||||
/* We don't have to do anything in asm for the return. */
|
||||
ret = FFI_TYPE_VOID;
|
||||
}
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,353 @@
|
||||
Status
|
||||
======
|
||||
|
||||
libffi-3.0.11 was released on *****************. Check the libffi web
|
||||
page for updates: <URL:http://sourceware.org/libffi/>.
|
||||
|
||||
|
||||
What is libffi?
|
||||
===============
|
||||
|
||||
Compilers for high level languages generate code that follow certain
|
||||
conventions. These conventions are necessary, in part, for separate
|
||||
compilation to work. One such convention is the "calling
|
||||
convention". The "calling convention" is essentially a set of
|
||||
assumptions made by the compiler about where function arguments will
|
||||
be found on entry to a function. A "calling convention" also specifies
|
||||
where the return value for a function is found.
|
||||
|
||||
Some programs may not know at the time of compilation what arguments
|
||||
are to be passed to a function. For instance, an interpreter may be
|
||||
told at run-time about the number and types of arguments used to call
|
||||
a given function. Libffi can be used in such programs to provide a
|
||||
bridge from the interpreter program to compiled code.
|
||||
|
||||
The libffi library provides a portable, high level programming
|
||||
interface to various calling conventions. This allows a programmer to
|
||||
call any function specified by a call interface description at run
|
||||
time.
|
||||
|
||||
FFI stands for Foreign Function Interface. A foreign function
|
||||
interface is the popular name for the interface that allows code
|
||||
written in one language to call code written in another language. The
|
||||
libffi library really only provides the lowest, machine dependent
|
||||
layer of a fully featured foreign function interface. A layer must
|
||||
exist above libffi that handles type conversions for values passed
|
||||
between the two languages.
|
||||
|
||||
|
||||
Supported Platforms
|
||||
===================
|
||||
|
||||
Libffi has been ported to many different platforms.
|
||||
For specific configuration details and testing status, please
|
||||
refer to the wiki page here:
|
||||
|
||||
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.11
|
||||
|
||||
At the time of release, the following basic configurations have been
|
||||
tested:
|
||||
|
||||
|--------------+------------------|
|
||||
| Architecture | Operating System |
|
||||
|--------------+------------------|
|
||||
| Alpha | Linux |
|
||||
| Alpha | Tru64 |
|
||||
| ARM | Linux |
|
||||
| ARM | iOS |
|
||||
| AVR32 | Linux |
|
||||
| HPPA | HPUX |
|
||||
| IA-64 | Linux |
|
||||
| M68K | RTEMS |
|
||||
| MIPS | IRIX |
|
||||
| MIPS | Linux |
|
||||
| MIPS | RTEMS |
|
||||
| MIPS64 | Linux |
|
||||
| PowerPC | AMIGA |
|
||||
| PowerPC | Linux |
|
||||
| PowerPC | Mac OSX |
|
||||
| PowerPC | FreeBSD |
|
||||
| PowerPC64 | Linux |
|
||||
| S390 | Linux |
|
||||
| S390X | Linux |
|
||||
| SPARC | Linux |
|
||||
| SPARC | Solaris |
|
||||
| SPARC64 | Linux |
|
||||
| SPARC64 | FreeBSD |
|
||||
| X86 | FreeBSD |
|
||||
| X86 | Interix |
|
||||
| X86 | kFreeBSD |
|
||||
| X86 | Linux |
|
||||
| X86 | Linux/x32 |
|
||||
| X86 | Mac OSX |
|
||||
| X86 | OpenBSD |
|
||||
| X86 | OS/2 |
|
||||
| X86 | Solaris |
|
||||
| X86 | Windows/Cygwin |
|
||||
| X86 | Windows/MingW |
|
||||
| X86-64 | FreeBSD |
|
||||
| X86-64 | Linux |
|
||||
| X86-64 | OpenBSD |
|
||||
| X86-64 | Windows/MingW |
|
||||
|--------------+------------------|
|
||||
|
||||
Please send additional platform test results to
|
||||
libffi-discuss@sourceware.org and feel free to update the wiki page
|
||||
above.
|
||||
|
||||
Installing libffi
|
||||
=================
|
||||
|
||||
First you must configure the distribution for your particular
|
||||
system. Go to the directory you wish to build libffi in and run the
|
||||
"configure" program found in the root directory of the libffi source
|
||||
distribution.
|
||||
|
||||
You may want to tell configure where to install the libffi library and
|
||||
header files. To do that, use the --prefix configure switch. Libffi
|
||||
will install under /usr/local by default.
|
||||
|
||||
If you want to enable extra run-time debugging checks use the the
|
||||
--enable-debug configure switch. This is useful when your program dies
|
||||
mysteriously while using libffi.
|
||||
|
||||
Another useful configure switch is --enable-purify-safety. Using this
|
||||
will add some extra code which will suppress certain warnings when you
|
||||
are using Purify with libffi. Only use this switch when using
|
||||
Purify, as it will slow down the library.
|
||||
|
||||
It's also possible to build libffi on Windows platforms with
|
||||
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
|
||||
wrapper script during configuration like so:
|
||||
|
||||
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
|
||||
|
||||
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
|
||||
You may also need to specify --build appropriately. When building with MSVC
|
||||
under a MingW environment, you may need to remove the line in configure
|
||||
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
|
||||
present in MingW, and is not required when using MingW-style paths.)
|
||||
|
||||
For iOS builds, refer to the build-ios.sh script for guidance.
|
||||
|
||||
Configure has many other options. Use "configure --help" to see them all.
|
||||
|
||||
Once configure has finished, type "make". Note that you must be using
|
||||
GNU make. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
|
||||
|
||||
To ensure that libffi is working as advertised, type "make check".
|
||||
This will require that you have DejaGNU installed.
|
||||
|
||||
To install the library and header files, type "make install".
|
||||
|
||||
|
||||
History
|
||||
=======
|
||||
|
||||
See the ChangeLog files for details.
|
||||
|
||||
3.0.11 MMM-DD-YY
|
||||
Add support for variadic functions (ffi_prep_cif_var).
|
||||
Add Linux/x32 support.
|
||||
Add thiscall, fastcall and MSVC cdecl support on Windows.
|
||||
Add Amiga and newer MacOS support.
|
||||
Fix Octeon and MC68881 support.
|
||||
Fix code pessimizations.
|
||||
Lots of build fixes.
|
||||
|
||||
3.0.10 Aug-23-11
|
||||
Add support for Apple's iOS.
|
||||
Add support for ARM VFP ABI.
|
||||
Add RTEMS support for MIPS and M68K.
|
||||
Fix instruction cache clearing problems on
|
||||
ARM and SPARC.
|
||||
Fix the N64 build on mips-sgi-irix6.5.
|
||||
Enable builds with Microsoft's compiler.
|
||||
Enable x86 builds with Oracle's Solaris compiler.
|
||||
Fix support for calling code compiled with Oracle's Sparc
|
||||
Solaris compiler.
|
||||
Testsuite fixes for Tru64 Unix.
|
||||
Additional platform support.
|
||||
|
||||
3.0.9 Dec-31-09
|
||||
Add AVR32 and win64 ports. Add ARM softfp support.
|
||||
Many fixes for AIX, Solaris, HP-UX, *BSD.
|
||||
Several PowerPC and x86-64 bug fixes.
|
||||
Build DLL for windows.
|
||||
|
||||
3.0.8 Dec-19-08
|
||||
Add *BSD, BeOS, and PA-Linux support.
|
||||
|
||||
3.0.7 Nov-11-08
|
||||
Fix for ppc FreeBSD.
|
||||
(thanks to Andreas Tobler)
|
||||
|
||||
3.0.6 Jul-17-08
|
||||
Fix for closures on sh.
|
||||
Mark the sh/sh64 stack as non-executable.
|
||||
(both thanks to Kaz Kojima)
|
||||
|
||||
3.0.5 Apr-3-08
|
||||
Fix libffi.pc file.
|
||||
Fix #define ARM for IcedTea users.
|
||||
Fix x86 closure bug.
|
||||
|
||||
3.0.4 Feb-24-08
|
||||
Fix x86 OpenBSD configury.
|
||||
|
||||
3.0.3 Feb-22-08
|
||||
Enable x86 OpenBSD thanks to Thomas Heller, and
|
||||
x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
|
||||
Clean up test instruction in README.
|
||||
|
||||
3.0.2 Feb-21-08
|
||||
Improved x86 FreeBSD support.
|
||||
Thanks to Björn König.
|
||||
|
||||
3.0.1 Feb-15-08
|
||||
Fix instruction cache flushing bug on MIPS.
|
||||
Thanks to David Daney.
|
||||
|
||||
3.0.0 Feb-15-08
|
||||
Many changes, mostly thanks to the GCC project.
|
||||
Cygnus Solutions is now Red Hat.
|
||||
|
||||
[10 years go by...]
|
||||
|
||||
1.20 Oct-5-98
|
||||
Raffaele Sena produces ARM port.
|
||||
|
||||
1.19 Oct-5-98
|
||||
Fixed x86 long double and long long return support.
|
||||
m68k bug fixes from Andreas Schwab.
|
||||
Patch for DU assembler compatibility for the Alpha from Richard
|
||||
Henderson.
|
||||
|
||||
1.18 Apr-17-98
|
||||
Bug fixes and MIPS configuration changes.
|
||||
|
||||
1.17 Feb-24-98
|
||||
Bug fixes and m68k port from Andreas Schwab. PowerPC port from
|
||||
Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
|
||||
|
||||
1.16 Feb-11-98
|
||||
Richard Henderson produces Alpha port.
|
||||
|
||||
1.15 Dec-4-97
|
||||
Fixed an n32 ABI bug. New libtool, auto* support.
|
||||
|
||||
1.14 May-13-97
|
||||
libtool is now used to generate shared and static libraries.
|
||||
Fixed a minor portability problem reported by Russ McManus
|
||||
<mcmanr@eq.gs.com>.
|
||||
|
||||
1.13 Dec-2-96
|
||||
Added --enable-purify-safety to keep Purify from complaining
|
||||
about certain low level code.
|
||||
Sparc fix for calling functions with < 6 args.
|
||||
Linux x86 a.out fix.
|
||||
|
||||
1.12 Nov-22-96
|
||||
Added missing ffi_type_void, needed for supporting void return
|
||||
types. Fixed test case for non MIPS machines. Cygnus Support
|
||||
is now Cygnus Solutions.
|
||||
|
||||
1.11 Oct-30-96
|
||||
Added notes about GNU make.
|
||||
|
||||
1.10 Oct-29-96
|
||||
Added configuration fix for non GNU compilers.
|
||||
|
||||
1.09 Oct-29-96
|
||||
Added --enable-debug configure switch. Clean-ups based on LCLint
|
||||
feedback. ffi_mips.h is always installed. Many configuration
|
||||
fixes. Fixed ffitest.c for sparc builds.
|
||||
|
||||
1.08 Oct-15-96
|
||||
Fixed n32 problem. Many clean-ups.
|
||||
|
||||
1.07 Oct-14-96
|
||||
Gordon Irlam rewrites v8.S again. Bug fixes.
|
||||
|
||||
1.06 Oct-14-96
|
||||
Gordon Irlam improved the sparc port.
|
||||
|
||||
1.05 Oct-14-96
|
||||
Interface changes based on feedback.
|
||||
|
||||
1.04 Oct-11-96
|
||||
Sparc port complete (modulo struct passing bug).
|
||||
|
||||
1.03 Oct-10-96
|
||||
Passing struct args, and returning struct values works for
|
||||
all architectures/calling conventions. Expanded tests.
|
||||
|
||||
1.02 Oct-9-96
|
||||
Added SGI n32 support. Fixed bugs in both o32 and Linux support.
|
||||
Added "make test".
|
||||
|
||||
1.01 Oct-8-96
|
||||
Fixed float passing bug in mips version. Restructured some
|
||||
of the code. Builds cleanly with SGI tools.
|
||||
|
||||
1.00 Oct-7-96
|
||||
First release. No public announcement.
|
||||
|
||||
|
||||
Authors & Credits
|
||||
=================
|
||||
|
||||
libffi was originally written by Anthony Green <green@redhat.com>.
|
||||
|
||||
The developers of the GNU Compiler Collection project have made
|
||||
innumerable valuable contributions. See the ChangeLog file for
|
||||
details.
|
||||
|
||||
Some of the ideas behind libffi were inspired by Gianni Mariani's free
|
||||
gencall library for Silicon Graphics machines.
|
||||
|
||||
The closure mechanism was designed and implemented by Kresten Krab
|
||||
Thorup.
|
||||
|
||||
Major processor architecture ports were contributed by the following
|
||||
developers:
|
||||
|
||||
alpha Richard Henderson
|
||||
arm Raffaele Sena
|
||||
cris Simon Posnjak, Hans-Peter Nilsson
|
||||
frv Anthony Green
|
||||
ia64 Hans Boehm
|
||||
m32r Kazuhiro Inaoka
|
||||
m68k Andreas Schwab
|
||||
mips Anthony Green, Casey Marshall
|
||||
mips64 David Daney
|
||||
pa Randolph Chung, Dave Anglin, Andreas Tobler
|
||||
powerpc Geoffrey Keating, Andreas Tobler,
|
||||
David Edelsohn, John Hornkvist
|
||||
powerpc64 Jakub Jelinek
|
||||
s390 Gerhard Tonn, Ulrich Weigand
|
||||
sh Kaz Kojima
|
||||
sh64 Kaz Kojima
|
||||
sparc Anthony Green, Gordon Irlam
|
||||
x86 Anthony Green, Jon Beniston
|
||||
x86-64 Bo Thorsen
|
||||
|
||||
Jesper Skov and Andrew Haley both did more than their fair share of
|
||||
stepping through the code and tracking down bugs.
|
||||
|
||||
Thanks also to Tom Tromey for bug fixes, documentation and
|
||||
configuration help.
|
||||
|
||||
Thanks to Jim Blandy, who provided some useful feedback on the libffi
|
||||
interface.
|
||||
|
||||
Andreas Tobler has done a tremendous amount of work on the testsuite.
|
||||
|
||||
Alex Oliva solved the executable page problem for SElinux.
|
||||
|
||||
The list above is almost certainly incomplete and inaccurate. I'm
|
||||
happy to make corrections or additions upon request.
|
||||
|
||||
If you have a problem, or have found a bug, please send a note to the
|
||||
author at green@moxielogic.com, or the project mailing list at
|
||||
libffi-discuss@sourceware.org.
|
||||
@@ -261,7 +261,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
FFI_ASSERT (cif->abi == FFI_SYSV);
|
||||
if (cif->abi != FFI_SYSV)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
*(unsigned short *)closure->tramp = 0x207c;
|
||||
*(void **)(closure->tramp + 2) = codeloc;
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
|
||||
sysv.S - Copyright (c) 1998 Andreas Schwab
|
||||
sysv.S - Copyright (c) 1998, 2012 Andreas Schwab
|
||||
Copyright (c) 2008 Red Hat, Inc.
|
||||
|
||||
m68k Foreign Function Interface
|
||||
@@ -87,7 +87,7 @@ ffi_call_SYSV:
|
||||
|
||||
| If the return value pointer is NULL, assume no return value.
|
||||
| NOTE: On the mc68000, tst on an address register is not supported.
|
||||
#if defined(__mc68000__) && !defined(__mcoldfire__)
|
||||
#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
|
||||
cmp.w #0, %a1
|
||||
#else
|
||||
tst.l %a1
|
||||
@@ -109,7 +109,7 @@ retlongint:
|
||||
retfloat:
|
||||
btst #2,%d2
|
||||
jbeq retdouble
|
||||
#if defined(__MC68881__)
|
||||
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||
fmove.s %fp0,(%a1)
|
||||
#else
|
||||
move.l %d0,(%a1)
|
||||
@@ -119,7 +119,7 @@ retfloat:
|
||||
retdouble:
|
||||
btst #3,%d2
|
||||
jbeq retlongdouble
|
||||
#if defined(__MC68881__)
|
||||
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||
fmove.d %fp0,(%a1)
|
||||
#else
|
||||
move.l %d0,(%a1)+
|
||||
@@ -130,7 +130,7 @@ retdouble:
|
||||
retlongdouble:
|
||||
btst #4,%d2
|
||||
jbeq retpointer
|
||||
#if defined(__MC68881__)
|
||||
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||
fmove.x %fp0,(%a1)
|
||||
#else
|
||||
move.l %d0,(%a1)+
|
||||
@@ -199,7 +199,7 @@ ffi_closure_SYSV:
|
||||
move.l (%a0),%d1
|
||||
jra .Lcls_epilogue
|
||||
.Lcls_ret_float:
|
||||
#if defined(__MC68881__)
|
||||
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||
fmove.s (%a0),%fp0
|
||||
#else
|
||||
move.l (%a0),%d0
|
||||
@@ -209,7 +209,7 @@ ffi_closure_SYSV:
|
||||
lsr.l #2,%d0
|
||||
jne 1f
|
||||
jcs .Lcls_ret_ldouble
|
||||
#if defined(__MC68881__)
|
||||
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||
fmove.d (%a0),%fp0
|
||||
#else
|
||||
move.l (%a0)+,%d0
|
||||
@@ -217,7 +217,7 @@ ffi_closure_SYSV:
|
||||
#endif
|
||||
jra .Lcls_epilogue
|
||||
.Lcls_ret_ldouble:
|
||||
#if defined(__MC68881__)
|
||||
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||
fmove.x (%a0),%fp0
|
||||
#else
|
||||
move.l (%a0)+,%d0
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -4,36 +4,37 @@ AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
SUBDIRS = include testsuite man
|
||||
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
src/arm/ffi.c src/arm/sysv.S src/arm/trampoline.S \
|
||||
src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \
|
||||
src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \
|
||||
src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \
|
||||
src/ia64/ia64_flags.h src/ia64/unix.S src/mips/ffi.c \
|
||||
src/mips/n32.S src/mips/o32.S src/mips/ffitarget.h \
|
||||
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
|
||||
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
|
||||
src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/linux64.S \
|
||||
src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \
|
||||
src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \
|
||||
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
|
||||
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
|
||||
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
|
||||
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c \
|
||||
src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \
|
||||
src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c \
|
||||
src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S \
|
||||
src/x86/win32.S src/x86/win64.S src/x86/darwin.S \
|
||||
src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S \
|
||||
src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c \
|
||||
src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/frv/eabi.S \
|
||||
src/frv/ffitarget.h src/dlmalloc.c src/moxie/ffi.c \
|
||||
src/moxie/eabi.S libtool-version ChangeLog.libffi \
|
||||
m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 \
|
||||
m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c \
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
|
||||
src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
|
||||
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
|
||||
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
|
||||
src/ia64/unix.S src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
|
||||
src/mips/ffitarget.h src/m32r/ffi.c src/m32r/sysv.S \
|
||||
src/m32r/ffitarget.h src/m68k/ffi.c src/m68k/sysv.S \
|
||||
src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S \
|
||||
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
|
||||
src/powerpc/ppc_closure.S src/powerpc/asm.h src/powerpc/aix.S \
|
||||
src/powerpc/darwin.S src/powerpc/aix_closure.S \
|
||||
src/powerpc/darwin_closure.S src/powerpc/ffi_darwin.c \
|
||||
src/powerpc/ffitarget.h src/s390/ffi.c src/s390/sysv.S \
|
||||
src/s390/ffitarget.h src/sh/ffi.c src/sh/sysv.S \
|
||||
src/sh/ffitarget.h src/sh64/ffi.c src/sh64/sysv.S \
|
||||
src/sh64/ffitarget.h src/sparc/v8.S src/sparc/v9.S \
|
||||
src/sparc/ffitarget.h src/sparc/ffi.c src/x86/darwin64.S \
|
||||
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
|
||||
src/x86/win64.S src/x86/freebsd.S src/x86/ffi64.c \
|
||||
src/x86/unix64.S src/x86/ffitarget.h src/pa/ffitarget.h \
|
||||
src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c \
|
||||
src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \
|
||||
src/moxie/ffi.c src/moxie/eabi.S libtool-version \
|
||||
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
|
||||
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 build-ios.sh \
|
||||
m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c \
|
||||
msvcc.sh
|
||||
|
||||
|
||||
info_TEXINFOS = doc/libffi.texi
|
||||
|
||||
## ################################################################
|
||||
@@ -159,6 +160,9 @@ endif
|
||||
if FRV
|
||||
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
|
||||
endif
|
||||
if MOXIE
|
||||
nodist_libffi_la_SOURCES += src/moxie/eabi.S src/moxie/ffi.c
|
||||
endif
|
||||
if S390
|
||||
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
|
||||
endif
|
||||
@@ -191,7 +195,7 @@ endif
|
||||
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
|
||||
|
||||
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS)
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS) -g
|
||||
|
||||
# No install-html or install-pdf support in automake yet
|
||||
.PHONY: install-html install-pdf
|
||||
@@ -57,15 +57,16 @@ target_triplet = @target@
|
||||
@AVR32_TRUE@am__append_19 = src/avr32/sysv.S src/avr32/ffi.c
|
||||
@LIBFFI_CRIS_TRUE@am__append_20 = src/cris/sysv.S src/cris/ffi.c
|
||||
@FRV_TRUE@am__append_21 = src/frv/eabi.S src/frv/ffi.c
|
||||
@S390_TRUE@am__append_22 = src/s390/sysv.S src/s390/ffi.c
|
||||
@X86_64_TRUE@am__append_23 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
|
||||
@SH_TRUE@am__append_24 = src/sh/sysv.S src/sh/ffi.c
|
||||
@SH64_TRUE@am__append_25 = src/sh64/sysv.S src/sh64/ffi.c
|
||||
@PA_LINUX_TRUE@am__append_26 = src/pa/linux.S src/pa/ffi.c
|
||||
@PA_HPUX_TRUE@am__append_27 = src/pa/hpux32.S src/pa/ffi.c
|
||||
@MOXIE_TRUE@am__append_22 = src/moxie/eabi.S src/moxie/ffi.c
|
||||
@S390_TRUE@am__append_23 = src/s390/sysv.S src/s390/ffi.c
|
||||
@X86_64_TRUE@am__append_24 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
|
||||
@SH_TRUE@am__append_25 = src/sh/sysv.S src/sh/ffi.c
|
||||
@SH64_TRUE@am__append_26 = src/sh64/sysv.S src/sh64/ffi.c
|
||||
@PA_LINUX_TRUE@am__append_27 = src/pa/linux.S src/pa/ffi.c
|
||||
@PA_HPUX_TRUE@am__append_28 = src/pa/hpux32.S src/pa/ffi.c
|
||||
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
|
||||
# MSVC, it can link against the debug CRT.
|
||||
@FFI_DEBUG_TRUE@am__append_28 = -DFFI_DEBUG
|
||||
@FFI_DEBUG_TRUE@am__append_29 = -DFFI_DEBUG
|
||||
subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
|
||||
@@ -74,9 +75,9 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
compile config.guess config.sub depcomp install-sh ltmain.sh \
|
||||
mdate-sh missing texinfo.tex
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
|
||||
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
|
||||
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
|
||||
$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
|
||||
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
|
||||
$(top_srcdir)/m4/ax_configure_args.m4 \
|
||||
$(top_srcdir)/m4/ax_enable_builddir.m4 \
|
||||
@@ -155,13 +156,14 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \
|
||||
@AVR32_TRUE@am__objects_19 = src/avr32/sysv.lo src/avr32/ffi.lo
|
||||
@LIBFFI_CRIS_TRUE@am__objects_20 = src/cris/sysv.lo src/cris/ffi.lo
|
||||
@FRV_TRUE@am__objects_21 = src/frv/eabi.lo src/frv/ffi.lo
|
||||
@S390_TRUE@am__objects_22 = src/s390/sysv.lo src/s390/ffi.lo
|
||||
@X86_64_TRUE@am__objects_23 = src/x86/ffi64.lo src/x86/unix64.lo \
|
||||
@MOXIE_TRUE@am__objects_22 = src/moxie/eabi.lo src/moxie/ffi.lo
|
||||
@S390_TRUE@am__objects_23 = src/s390/sysv.lo src/s390/ffi.lo
|
||||
@X86_64_TRUE@am__objects_24 = src/x86/ffi64.lo src/x86/unix64.lo \
|
||||
@X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
|
||||
@SH_TRUE@am__objects_24 = src/sh/sysv.lo src/sh/ffi.lo
|
||||
@SH64_TRUE@am__objects_25 = src/sh64/sysv.lo src/sh64/ffi.lo
|
||||
@PA_LINUX_TRUE@am__objects_26 = src/pa/linux.lo src/pa/ffi.lo
|
||||
@PA_HPUX_TRUE@am__objects_27 = src/pa/hpux32.lo src/pa/ffi.lo
|
||||
@SH_TRUE@am__objects_25 = src/sh/sysv.lo src/sh/ffi.lo
|
||||
@SH64_TRUE@am__objects_26 = src/sh64/sysv.lo src/sh64/ffi.lo
|
||||
@PA_LINUX_TRUE@am__objects_27 = src/pa/linux.lo src/pa/ffi.lo
|
||||
@PA_HPUX_TRUE@am__objects_28 = src/pa/hpux32.lo src/pa/ffi.lo
|
||||
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
|
||||
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
|
||||
@@ -171,17 +173,17 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
|
||||
$(am__objects_21) $(am__objects_22) $(am__objects_23) \
|
||||
$(am__objects_24) $(am__objects_25) $(am__objects_26) \
|
||||
$(am__objects_27)
|
||||
$(am__objects_27) $(am__objects_28)
|
||||
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
|
||||
$(nodist_libffi_la_OBJECTS)
|
||||
libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
libffi_convenience_la_LIBADD =
|
||||
am__objects_28 = src/prep_cif.lo src/types.lo src/raw_api.lo \
|
||||
am__objects_29 = src/prep_cif.lo src/types.lo src/raw_api.lo \
|
||||
src/java_raw_api.lo src/closures.lo
|
||||
am_libffi_convenience_la_OBJECTS = $(am__objects_28)
|
||||
am__objects_29 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
am_libffi_convenience_la_OBJECTS = $(am__objects_29)
|
||||
am__objects_30 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
|
||||
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
|
||||
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
|
||||
@@ -189,8 +191,9 @@ am__objects_29 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_16) $(am__objects_17) $(am__objects_18) \
|
||||
$(am__objects_19) $(am__objects_20) $(am__objects_21) \
|
||||
$(am__objects_22) $(am__objects_23) $(am__objects_24) \
|
||||
$(am__objects_25) $(am__objects_26) $(am__objects_27)
|
||||
nodist_libffi_convenience_la_OBJECTS = $(am__objects_29)
|
||||
$(am__objects_25) $(am__objects_26) $(am__objects_27) \
|
||||
$(am__objects_28)
|
||||
nodist_libffi_convenience_la_OBJECTS = $(am__objects_30)
|
||||
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
|
||||
$(nodist_libffi_convenience_la_OBJECTS)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
@@ -414,34 +417,34 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
SUBDIRS = include testsuite man
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
src/arm/ffi.c src/arm/sysv.S src/arm/trampoline.S \
|
||||
src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \
|
||||
src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \
|
||||
src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \
|
||||
src/ia64/ia64_flags.h src/ia64/unix.S src/mips/ffi.c \
|
||||
src/mips/n32.S src/mips/o32.S src/mips/ffitarget.h \
|
||||
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
|
||||
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
|
||||
src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/linux64.S \
|
||||
src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \
|
||||
src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \
|
||||
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
|
||||
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
|
||||
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
|
||||
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c \
|
||||
src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \
|
||||
src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c \
|
||||
src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S \
|
||||
src/x86/win32.S src/x86/win64.S src/x86/darwin.S \
|
||||
src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S \
|
||||
src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c \
|
||||
src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/frv/eabi.S \
|
||||
src/frv/ffitarget.h src/dlmalloc.c src/moxie/ffi.c \
|
||||
src/moxie/eabi.S libtool-version ChangeLog.libffi \
|
||||
m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 \
|
||||
m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c \
|
||||
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
|
||||
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
|
||||
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
|
||||
src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
|
||||
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
|
||||
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
|
||||
src/ia64/unix.S src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
|
||||
src/mips/ffitarget.h src/m32r/ffi.c src/m32r/sysv.S \
|
||||
src/m32r/ffitarget.h src/m68k/ffi.c src/m68k/sysv.S \
|
||||
src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S \
|
||||
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
|
||||
src/powerpc/ppc_closure.S src/powerpc/asm.h src/powerpc/aix.S \
|
||||
src/powerpc/darwin.S src/powerpc/aix_closure.S \
|
||||
src/powerpc/darwin_closure.S src/powerpc/ffi_darwin.c \
|
||||
src/powerpc/ffitarget.h src/s390/ffi.c src/s390/sysv.S \
|
||||
src/s390/ffitarget.h src/sh/ffi.c src/sh/sysv.S \
|
||||
src/sh/ffitarget.h src/sh64/ffi.c src/sh64/sysv.S \
|
||||
src/sh64/ffitarget.h src/sparc/v8.S src/sparc/v9.S \
|
||||
src/sparc/ffitarget.h src/sparc/ffi.c src/x86/darwin64.S \
|
||||
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
|
||||
src/x86/win64.S src/x86/freebsd.S src/x86/ffi64.c \
|
||||
src/x86/unix64.S src/x86/ffitarget.h src/pa/ffitarget.h \
|
||||
src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c \
|
||||
src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \
|
||||
src/moxie/ffi.c src/moxie/eabi.S libtool-version \
|
||||
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
|
||||
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 build-ios.sh \
|
||||
m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c \
|
||||
msvcc.sh
|
||||
|
||||
info_TEXINFOS = doc/libffi.texi
|
||||
@@ -502,13 +505,13 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
|
||||
$(am__append_18) $(am__append_19) $(am__append_20) \
|
||||
$(am__append_21) $(am__append_22) $(am__append_23) \
|
||||
$(am__append_24) $(am__append_25) $(am__append_26) \
|
||||
$(am__append_27)
|
||||
$(am__append_27) $(am__append_28)
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
|
||||
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
||||
AM_CFLAGS = -g $(am__append_28)
|
||||
AM_CFLAGS = -g $(am__append_29)
|
||||
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
|
||||
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS)
|
||||
AM_CCASFLAGS = $(AM_CPPFLAGS) -g
|
||||
all: fficonfig.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
@@ -773,6 +776,16 @@ src/frv/eabi.lo: src/frv/$(am__dirstamp) \
|
||||
src/frv/$(DEPDIR)/$(am__dirstamp)
|
||||
src/frv/ffi.lo: src/frv/$(am__dirstamp) \
|
||||
src/frv/$(DEPDIR)/$(am__dirstamp)
|
||||
src/moxie/$(am__dirstamp):
|
||||
@$(MKDIR_P) src/moxie
|
||||
@: > src/moxie/$(am__dirstamp)
|
||||
src/moxie/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) src/moxie/$(DEPDIR)
|
||||
@: > src/moxie/$(DEPDIR)/$(am__dirstamp)
|
||||
src/moxie/eabi.lo: src/moxie/$(am__dirstamp) \
|
||||
src/moxie/$(DEPDIR)/$(am__dirstamp)
|
||||
src/moxie/ffi.lo: src/moxie/$(am__dirstamp) \
|
||||
src/moxie/$(DEPDIR)/$(am__dirstamp)
|
||||
src/s390/$(am__dirstamp):
|
||||
@$(MKDIR_P) src/s390
|
||||
@: > src/s390/$(am__dirstamp)
|
||||
@@ -868,6 +881,10 @@ mostlyclean-compile:
|
||||
-rm -f src/mips/n32.lo
|
||||
-rm -f src/mips/o32.$(OBJEXT)
|
||||
-rm -f src/mips/o32.lo
|
||||
-rm -f src/moxie/eabi.$(OBJEXT)
|
||||
-rm -f src/moxie/eabi.lo
|
||||
-rm -f src/moxie/ffi.$(OBJEXT)
|
||||
-rm -f src/moxie/ffi.lo
|
||||
-rm -f src/pa/ffi.$(OBJEXT)
|
||||
-rm -f src/pa/ffi.lo
|
||||
-rm -f src/pa/hpux32.$(OBJEXT)
|
||||
@@ -966,6 +983,8 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/ffi.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/n32.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/eabi.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/ffi.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@
|
||||
@@ -1061,6 +1080,7 @@ clean-libtool:
|
||||
-rm -rf src/m32r/.libs src/m32r/_libs
|
||||
-rm -rf src/m68k/.libs src/m68k/_libs
|
||||
-rm -rf src/mips/.libs src/mips/_libs
|
||||
-rm -rf src/moxie/.libs src/moxie/_libs
|
||||
-rm -rf src/pa/.libs src/pa/_libs
|
||||
-rm -rf src/powerpc/.libs src/powerpc/_libs
|
||||
-rm -rf src/s390/.libs src/s390/_libs
|
||||
@@ -1620,6 +1640,8 @@ distclean-generic:
|
||||
-rm -f src/m68k/$(am__dirstamp)
|
||||
-rm -f src/mips/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f src/mips/$(am__dirstamp)
|
||||
-rm -f src/moxie/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f src/moxie/$(am__dirstamp)
|
||||
-rm -f src/pa/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f src/pa/$(am__dirstamp)
|
||||
-rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp)
|
||||
@@ -1645,7 +1667,7 @@ clean-am: clean-aminfo clean-generic clean-libLTLIBRARIES \
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
|
||||
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags
|
||||
@@ -1765,7 +1787,7 @@ installcheck-am:
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
|
||||
-rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
|
||||
maintainer-clean-generic maintainer-clean-vti
|
||||
@@ -86,11 +86,15 @@ extern "C" {
|
||||
#else
|
||||
# ifdef LLONG_MAX
|
||||
# define FFI_LONG_LONG_MAX LLONG_MAX
|
||||
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
|
||||
# undef FFI_64_BIT_MAX
|
||||
# define FFI_64_BIT_MAX 9223372036854775807LL
|
||||
# endif /* _AIX52 or newer */
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifdef _AIX
|
||||
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
|
||||
# ifndef __PPC64__
|
||||
# if defined (__IBMC__) || defined (__IBMCPP__)
|
||||
# define FFI_LONG_LONG_MAX LONGLONG_MAX
|
||||
@@ -203,6 +207,15 @@ typedef struct {
|
||||
#endif
|
||||
} ffi_cif;
|
||||
|
||||
/* Used internally, but overridden by some architectures */
|
||||
ffi_status ffi_prep_cif_core(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int isvariadic,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
/* ---- Definitions for the raw API -------------------------------------- */
|
||||
|
||||
#ifndef FFI_SIZEOF_ARG
|
||||
@@ -380,6 +393,13 @@ ffi_status ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
@@ -48,6 +48,13 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
#ifdef X86_WIN32
|
||||
size_t p_stack_args[2];
|
||||
void *p_stack_data[2];
|
||||
char *argp2 = stack;
|
||||
int stack_args_count = 0;
|
||||
int cabi = ecif->cif->abi;
|
||||
#endif
|
||||
|
||||
argp = stack;
|
||||
|
||||
@@ -59,6 +66,16 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
)
|
||||
{
|
||||
*(void **) argp = ecif->rvalue;
|
||||
#ifdef X86_WIN32
|
||||
/* For fastcall/thiscall this is first register-passed
|
||||
argument. */
|
||||
if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
|
||||
{
|
||||
p_stack_args[stack_args_count] = sizeof (void*);
|
||||
p_stack_data[stack_args_count] = argp;
|
||||
++stack_args_count;
|
||||
}
|
||||
#endif
|
||||
argp += sizeof(void*);
|
||||
}
|
||||
|
||||
@@ -134,6 +151,24 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
memcpy(argp, *p_argv, z);
|
||||
}
|
||||
|
||||
#ifdef X86_WIN32
|
||||
/* For thiscall/fastcall convention register-passed arguments
|
||||
are the first two none-floating-point arguments with a size
|
||||
smaller or equal to sizeof (void*). */
|
||||
if ((cabi == FFI_THISCALL && stack_args_count < 1)
|
||||
|| (cabi == FFI_FASTCALL && stack_args_count < 2))
|
||||
{
|
||||
if (z <= 4
|
||||
&& ((*p_arg)->type != FFI_TYPE_FLOAT
|
||||
&& (*p_arg)->type != FFI_TYPE_STRUCT))
|
||||
{
|
||||
p_stack_args[stack_args_count] = z;
|
||||
p_stack_data[stack_args_count] = argp;
|
||||
++stack_args_count;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
p_argv++;
|
||||
#ifdef X86_WIN64
|
||||
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
|
||||
@@ -141,7 +176,45 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
argp += z;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef X86_WIN32
|
||||
/* We need to move the register-passed arguments for thiscall/fastcall
|
||||
on top of stack, so that those can be moved to registers ecx/edx by
|
||||
call-handler. */
|
||||
if (stack_args_count > 0)
|
||||
{
|
||||
size_t zz = (p_stack_args[0] + 3) & ~3;
|
||||
char *h;
|
||||
|
||||
/* Move first argument to top-stack position. */
|
||||
if (p_stack_data[0] != argp2)
|
||||
{
|
||||
h = alloca (zz + 1);
|
||||
memcpy (h, p_stack_data[0], zz);
|
||||
memmove (argp2 + zz, argp2,
|
||||
(size_t) ((char *) p_stack_data[0] - (char*)argp2));
|
||||
memcpy (argp2, h, zz);
|
||||
}
|
||||
|
||||
argp2 += zz;
|
||||
--stack_args_count;
|
||||
if (zz > 4)
|
||||
stack_args_count = 0;
|
||||
|
||||
/* If we have a second argument, then move it on top
|
||||
after the first one. */
|
||||
if (stack_args_count > 0 && p_stack_data[1] != argp2)
|
||||
{
|
||||
zz = p_stack_args[1];
|
||||
zz = (zz + 3) & ~3;
|
||||
h = alloca (zz + 1);
|
||||
h = alloca (zz + 1);
|
||||
memcpy (h, p_stack_data[1], zz);
|
||||
memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2));
|
||||
memcpy (argp2, h, zz);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -250,7 +323,7 @@ ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
|
||||
#elif defined(X86_WIN32)
|
||||
extern void
|
||||
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
#else
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
@@ -295,8 +368,37 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
#elif defined(X86_WIN32)
|
||||
case FFI_SYSV:
|
||||
case FFI_STDCALL:
|
||||
ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
case FFI_THISCALL:
|
||||
case FFI_FASTCALL:
|
||||
{
|
||||
unsigned int abi = cif->abi;
|
||||
unsigned int i, passed_regs = 0;
|
||||
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
++passed_regs;
|
||||
|
||||
for (i=0; i < cif->nargs && passed_regs < 2;i++)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|
||||
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
|
||||
continue;
|
||||
sz = (cif->arg_types[i]->size + 3) & ~3;
|
||||
if (sz == 0 || sz > 4)
|
||||
continue;
|
||||
++passed_regs;
|
||||
}
|
||||
if (passed_regs < 2 && abi == FFI_FASTCALL)
|
||||
abi = FFI_THISCALL;
|
||||
if (passed_regs < 1 && abi == FFI_THISCALL)
|
||||
abi = FFI_STDCALL;
|
||||
ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case FFI_SYSV:
|
||||
@@ -324,8 +426,12 @@ unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
|
||||
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
#ifdef X86_WIN32
|
||||
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
|
||||
__attribute__ ((regparm(1)));
|
||||
#endif
|
||||
#ifdef X86_WIN64
|
||||
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
|
||||
@@ -485,6 +591,33 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
||||
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
|
||||
}
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned int __dis = __fun - (__ctx + 49); \
|
||||
unsigned short __size = (unsigned short)(SIZE); \
|
||||
*(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
|
||||
*(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
|
||||
*(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
|
||||
*(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
|
||||
*(unsigned char*) &__tramp[13] = 0xb8; \
|
||||
*(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
|
||||
*(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
|
||||
*(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
|
||||
*(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
|
||||
*(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
|
||||
*(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
|
||||
*(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
|
||||
*(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
|
||||
*(unsigned char*) &__tramp[39] = 0xb8; \
|
||||
*(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
|
||||
*(unsigned char *) &__tramp[44] = 0xe8; \
|
||||
*(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
|
||||
*(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
|
||||
*(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
|
||||
}
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
@@ -527,6 +660,13 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
||||
(void*)codeloc);
|
||||
}
|
||||
#ifdef X86_WIN32
|
||||
else if (cif->abi == FFI_THISCALL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
|
||||
&ffi_closure_THISCALL,
|
||||
(void*)codeloc,
|
||||
cif->bytes);
|
||||
}
|
||||
else if (cif->abi == FFI_STDCALL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
|
||||
@@ -561,6 +701,9 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
||||
int i;
|
||||
|
||||
if (cif->abi != FFI_SYSV) {
|
||||
#ifdef X86_WIN32
|
||||
if (cif->abi != FFI_THISCALL)
|
||||
#endif
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
@@ -575,10 +718,20 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
||||
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
|
||||
}
|
||||
|
||||
|
||||
#ifdef X86_WIN32
|
||||
if (cif->abi == FFI_SYSV)
|
||||
{
|
||||
#endif
|
||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
|
||||
codeloc);
|
||||
|
||||
#ifdef X86_WIN32
|
||||
}
|
||||
else if (cif->abi == FFI_THISCALL)
|
||||
{
|
||||
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL,
|
||||
codeloc, cif->bytes);
|
||||
}
|
||||
#endif
|
||||
closure->cif = cif;
|
||||
closure->user_data = user_data;
|
||||
closure->fun = fun;
|
||||
@@ -623,8 +776,37 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
||||
#ifdef X86_WIN32
|
||||
case FFI_SYSV:
|
||||
case FFI_STDCALL:
|
||||
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
case FFI_THISCALL:
|
||||
case FFI_FASTCALL:
|
||||
{
|
||||
unsigned int abi = cif->abi;
|
||||
unsigned int i, passed_regs = 0;
|
||||
|
||||
if (cif->flags == FFI_TYPE_STRUCT)
|
||||
++passed_regs;
|
||||
|
||||
for (i=0; i < cif->nargs && passed_regs < 2;i++)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|
||||
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
|
||||
continue;
|
||||
sz = (cif->arg_types[i]->size + 3) & ~3;
|
||||
if (sz == 0 || sz > 4)
|
||||
continue;
|
||||
++passed_regs;
|
||||
}
|
||||
if (passed_regs < 2 && abi == FFI_FASTCALL)
|
||||
cif->abi = abi = FFI_THISCALL;
|
||||
if (passed_regs < 1 && abi == FFI_THISCALL)
|
||||
cif->abi = abi = FFI_STDCALL;
|
||||
ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case FFI_SYSV:
|
||||
@@ -1,6 +1,7 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003, 2010 Red Hat, Inc.
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
ffitarget.h - Copyright (c) 2012 Anthony Green
|
||||
Copyright (c) 1996-2003, 2010 Red Hat, Inc.
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Target configuration macros for x86 and x86-64.
|
||||
|
||||
@@ -29,6 +30,10 @@
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
#ifndef LIBFFI_H
|
||||
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
|
||||
#endif
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
/* For code common to all platforms on x86 and x86_64. */
|
||||
@@ -56,9 +61,15 @@ typedef unsigned long long ffi_arg;
|
||||
typedef long long ffi_sarg;
|
||||
#endif
|
||||
#else
|
||||
#if defined __x86_64__ && !defined __LP64__
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef long long ffi_sarg;
|
||||
#else
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
@@ -67,6 +78,8 @@ typedef enum ffi_abi {
|
||||
#ifdef X86_WIN32
|
||||
FFI_SYSV,
|
||||
FFI_STDCALL,
|
||||
FFI_THISCALL,
|
||||
FFI_FASTCALL,
|
||||
FFI_LAST_ABI,
|
||||
/* TODO: Add fastcall support for the sake of completeness */
|
||||
FFI_DEFAULT_ABI = FFI_SYSV
|
||||
@@ -102,7 +115,7 @@ typedef enum ffi_abi {
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
#else
|
||||
#ifdef X86_WIN32
|
||||
#define FFI_TRAMPOLINE_SIZE 13
|
||||
#define FFI_TRAMPOLINE_SIZE 52
|
||||
#else
|
||||
#ifdef X86_WIN64
|
||||
#define FFI_TRAMPOLINE_SIZE 29
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,64 @@
|
||||
/* Area: closure_call (thiscall convention)
|
||||
Purpose: Check handling when caller expects thiscall callee
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <ktietz@redhat.com> */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static void
|
||||
closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(int *)args[0] + (int)(*(int *)args[1])
|
||||
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
|
||||
+ (int)(intptr_t)userdata;
|
||||
|
||||
printf("%d %d %d %d: %d\n",
|
||||
(int)*(int *)args[0], (int)(*(int *)args[1]),
|
||||
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
|
||||
(int)*(ffi_arg *)resp);
|
||||
|
||||
}
|
||||
|
||||
typedef int (__thiscall *closure_test_type0)(int, int, int, int);
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
ffi_type * cl_arg_types[17];
|
||||
int res;
|
||||
void* sp_pre;
|
||||
void* sp_post;
|
||||
char buf[1024];
|
||||
|
||||
cl_arg_types[0] = &ffi_type_uint;
|
||||
cl_arg_types[1] = &ffi_type_uint;
|
||||
cl_arg_types[2] = &ffi_type_uint;
|
||||
cl_arg_types[3] = &ffi_type_uint;
|
||||
cl_arg_types[4] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
|
||||
(void *) 3 /* userdata */, code) == FFI_OK);
|
||||
|
||||
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
|
||||
res = (*(closure_test_type0)code)(0, 1, 2, 3);
|
||||
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
|
||||
/* { dg-output "0 1 2 3: 9" } */
|
||||
|
||||
printf("res: %d\n",res);
|
||||
/* { dg-output "\nres: 9" } */
|
||||
|
||||
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
|
||||
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
|
||||
/* { dg-output "\nstack pointer match" } */
|
||||
exit(0);
|
||||
}
|
||||
+1
-1
@@ -129,7 +129,7 @@ int main (void)
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res = (ffi_arg)((void*(*)(void*, void*))(code))(arg1, arg2);
|
||||
res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
|
||||
|
||||
printf("res: 0x%08x\n", (unsigned int) res);
|
||||
// { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
|
||||
@@ -0,0 +1,50 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall fct call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_f(char *s, float a)
|
||||
{
|
||||
return (size_t) ((int) strlen(s) + (int) a);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
float v2;
|
||||
args[0] = &ffi_type_pointer;
|
||||
args[1] = &ffi_type_float;
|
||||
values[0] = (void*) &s;
|
||||
values[1] = (void*) &v2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
v2 = 0.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 1);
|
||||
|
||||
s = "1234567";
|
||||
v2 = -1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 6);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
v2 = 1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 26);
|
||||
|
||||
printf("fastcall fct1 tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall fct call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s)
|
||||
{
|
||||
return (size_t) ((int) strlen(s) + (int) a);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
float v2;
|
||||
args[1] = &ffi_type_pointer;
|
||||
args[0] = &ffi_type_float;
|
||||
values[1] = (void*) &s;
|
||||
values[0] = (void*) &v2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
v2 = 0.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 1);
|
||||
|
||||
s = "1234567";
|
||||
v2 = -1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 6);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
v2 = 1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 26);
|
||||
|
||||
printf("fastcall fct2 tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall f call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s, int i)
|
||||
{
|
||||
return (size_t) ((int) strlen(s) + (int) a + i);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
int v1;
|
||||
float v2;
|
||||
args[2] = &ffi_type_sint;
|
||||
args[1] = &ffi_type_pointer;
|
||||
args[0] = &ffi_type_float;
|
||||
values[2] = (void*) &v1;
|
||||
values[1] = (void*) &s;
|
||||
values[0] = (void*) &v2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 3,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
v1 = 1;
|
||||
v2 = 0.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 2);
|
||||
|
||||
s = "1234567";
|
||||
v2 = -1.0;
|
||||
v1 = -2;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 4);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
v2 = 1.0;
|
||||
v1 = 2;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 28);
|
||||
|
||||
printf("fastcall fct3 tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
+4
@@ -67,6 +67,8 @@
|
||||
#define PRIdLL "ld"
|
||||
#undef PRIuLL
|
||||
#define PRIuLL "lu"
|
||||
#define PRId8 "hd"
|
||||
#define PRIu8 "hu"
|
||||
#define PRId64 "ld"
|
||||
#define PRIu64 "lu"
|
||||
#define PRIuPTR "lu"
|
||||
@@ -81,6 +83,8 @@
|
||||
#if defined(__sgi)
|
||||
/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
|
||||
compilations. */
|
||||
#define PRId8 "hhd"
|
||||
#define PRIu8 "hhu"
|
||||
#if (_MIPS_SZLONG == 32)
|
||||
#define PRId64 "lld"
|
||||
#define PRIu64 "llu"
|
||||
+16
-16
@@ -129,14 +129,14 @@ test_large_fn(
|
||||
ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4),
|
||||
ui8_5 + 5, si8_5 + 5};
|
||||
|
||||
printf("%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd: "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n",
|
||||
printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
|
||||
ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
|
||||
ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
|
||||
ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
|
||||
@@ -296,10 +296,10 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
|
||||
|
||||
ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
|
||||
// { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
|
||||
printf("res: %hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n",
|
||||
printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
|
||||
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
|
||||
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
|
||||
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
|
||||
@@ -324,10 +324,10 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
|
||||
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
|
||||
ui8, si8);
|
||||
// { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
|
||||
printf("res: %hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n",
|
||||
printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
|
||||
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
|
||||
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
|
||||
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall strlen call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_strlen(char *s)
|
||||
{
|
||||
return (strlen(s));
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
args[0] = &ffi_type_pointer;
|
||||
values[0] = (void*) &s;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values);
|
||||
CHECK(rint == 1);
|
||||
|
||||
s = "1234567";
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values);
|
||||
CHECK(rint == 7);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values);
|
||||
CHECK(rint == 25);
|
||||
|
||||
printf("fastcall strlen tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário