diff options
author | Andrew Haley <aph@redhat.com> | 2009-06-05 12:55:06 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2009-06-05 12:55:06 +0000 |
commit | 56faec5e60255d9bec6669d919c1b7318282a115 (patch) | |
tree | a229251793b1d52c44d64defbf272fc8dcde0e40 /libffi | |
parent | 47d1f19159314bb55589dfea175435b52234a036 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | libffi/src/x86/ffi.c | 50 | ||||
-rw-r--r-- | libffi/src/x86/ffitarget.h | 4 |
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 |