aboutsummaryrefslogtreecommitdiff
path: root/libffi
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2009-06-05 12:55:06 +0000
committerAndrew Haley <aph@gcc.gnu.org>2009-06-05 12:55:06 +0000
commit56faec5e60255d9bec6669d919c1b7318282a115 (patch)
treea229251793b1d52c44d64defbf272fc8dcde0e40 /libffi
parent47d1f19159314bb55589dfea175435b52234a036 (diff)
downloadgcc-56faec5e60255d9bec6669d919c1b7318282a115.zip
gcc-56faec5e60255d9bec6669d919c1b7318282a115.tar.gz
gcc-56faec5e60255d9bec6669d919c1b7318282a115.tar.bz2
ffitarget.h, ffi.c: Merge stdcall changes from libffi.
2009-06-05 Andrew Haley <aph@redhat.com> * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from libffi. From-SVN: r148207
Diffstat (limited to 'libffi')
-rw-r--r--libffi/ChangeLog5
-rw-r--r--libffi/src/x86/ffi.c50
-rw-r--r--libffi/src/x86/ffitarget.h4
3 files changed, 50 insertions, 9 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 5587978..bf34ca1 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-05 Andrew Haley <aph@redhat.com>
+
+ * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from
+ libffi.
+
2009-06-04 Andrew Haley <aph@redhat.com>
* src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
index 2bca56e..767effb 100644
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007 Red Hat, Inc.
+ 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
@@ -236,6 +236,10 @@ 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_STDCALL (ffi_closure *)
+ __attribute__ ((regparm(1)));
+#endif
/* This function is jumped to by the trampoline */
@@ -245,7 +249,7 @@ ffi_closure_SYSV_inner (closure, respp, args)
void **respp;
void *args;
{
- // our various things...
+ /* our various things... */
ffi_cif *cif;
void **arg_area;
@@ -311,13 +315,26 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
- unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \
+ 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_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 */
@@ -328,11 +345,24 @@ ffi_prep_closure_loc (ffi_closure* closure,
void *user_data,
void *codeloc)
{
- FFI_ASSERT (cif->abi == FFI_SYSV);
-
- FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
- &ffi_closure_SYSV, \
- codeloc);
+ if (cif->abi == FFI_SYSV)
+ {
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+ &ffi_closure_SYSV,
+ (void*)codeloc);
+ }
+#ifdef X86_WIN32
+ else if (cif->abi == FFI_STDCALL)
+ {
+ FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
+ &ffi_closure_STDCALL,
+ (void*)codeloc, cif->bytes);
+ }
+#endif
+ else
+ {
+ return FFI_BAD_ABI;
+ }
closure->cif = cif;
closure->user_data = user_data;
@@ -354,7 +384,9 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
{
int i;
- FFI_ASSERT (cif->abi == FFI_SYSV);
+ if (cif->abi != FFI_SYSV) {
+ 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
diff --git a/libffi/src/x86/ffitarget.h b/libffi/src/x86/ffitarget.h
index 25dcc1b..8178d06 100644
--- a/libffi/src/x86/ffitarget.h
+++ b/libffi/src/x86/ffitarget.h
@@ -78,7 +78,11 @@ typedef enum ffi_abi {
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#else
+#ifdef X86_WIN32
+#define FFI_TRAMPOLINE_SIZE 13
+#else
#define FFI_TRAMPOLINE_SIZE 10
+#endif
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif