From fc8bf09a48c6e220350727814d2c49d45c80dbf2 Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Thu, 8 Aug 2013 20:37:02 -0700 Subject: libffi: fix arm trampoline to work on arm v7 big endian (be8) case cffi code creates trampoline for python callback function, which is supposed to be called from another C function and it does not take into account that in ARMv7a in big endian mode instructions are still in little endian. Since written by big endian code they have to be byteswapped. Proposed fix uses byteswap codes for instructions. Here is python code snippet that will fail when libffi is used by ctypes in python code (func1 and func2 are C functions): from ctypes import * mylib = CDLL("libmytest.so") func1 = mylib.func1 print func1(1, 2) CBFUNC = CFUNCTYPE(c_int, c_int, c_int) def myfunc2(a, b): return a * a + b * b cb_func = CBFUNC(myfunc2) func2 = mylib.func2 print func2(cb_func, 1, 2) code will produce illegal instruction when func2 will call myfunc2 through trampoline Signed-off-by: Victor Kamensky Signed-off-by: Riku Voipio --- .../libffi/libffi/libffi_armeb_be8.patch | 37 ++++++++++++++++++++++ .../recipes-gnome/libffi/libffi_3.0.13.bbappend | 3 ++ 2 files changed, 40 insertions(+) create mode 100644 meta-bigendian/recipes-gnome/libffi/libffi/libffi_armeb_be8.patch create mode 100644 meta-bigendian/recipes-gnome/libffi/libffi_3.0.13.bbappend (limited to 'meta-bigendian') diff --git a/meta-bigendian/recipes-gnome/libffi/libffi/libffi_armeb_be8.patch b/meta-bigendian/recipes-gnome/libffi/libffi/libffi_armeb_be8.patch new file mode 100644 index 00000000..7efa58e8 --- /dev/null +++ b/meta-bigendian/recipes-gnome/libffi/libffi/libffi_armeb_be8.patch @@ -0,0 +1,37 @@ +Index: libffi-3.0.13/src/arm/ffi.c +=================================================================== +--- libffi-3.0.13.orig/src/arm/ffi.c ++++ libffi-3.0.13/src/arm/ffi.c +@@ -582,6 +582,7 @@ ffi_closure_free (void *ptr) + + #else + ++#if !(defined(__ARMEB__) && defined(__ARM_ARCH_7A__)) + #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ + ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + unsigned int __fun = (unsigned int)(FUN); \ +@@ -595,7 +596,23 @@ ffi_closure_free (void *ptr) + /* Clear instruction \ + mapping. */ \ + }) +- ++#else /* armv7 big endian: be8 instructions are still little endian */ ++#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 char *insns = (unsigned char *)(CTX); \ ++ *(unsigned int*) &__tramp[0] = 0x0f002de9; /* swab(0xe92d000f, 4) - stmfd sp!, {r0-r3} */ \ ++ *(unsigned int*) &__tramp[4] = 0x00009fe5; /* swab(0xe59f0000, 4) - ldr r0, [pc] */ \ ++ *(unsigned int*) &__tramp[8] = 0x00f09fe5; /* swab(0xe59ff000, 4) - ldr pc, [pc] */ \ ++ *(unsigned int*) &__tramp[12] = __ctx; \ ++ *(unsigned int*) &__tramp[16] = __fun; \ ++ __clear_cache((&__tramp[0]), (&__tramp[19])); /* Clear data mapping. */ \ ++ __clear_cache(insns, insns + 3 * sizeof (unsigned int)); \ ++ /* Clear instruction \ ++ mapping. */ \ ++ }) ++#endif + #endif + + /* the cif must already be prep'ed */ diff --git a/meta-bigendian/recipes-gnome/libffi/libffi_3.0.13.bbappend b/meta-bigendian/recipes-gnome/libffi/libffi_3.0.13.bbappend new file mode 100644 index 00000000..1774c0c4 --- /dev/null +++ b/meta-bigendian/recipes-gnome/libffi/libffi_3.0.13.bbappend @@ -0,0 +1,3 @@ +FILESEXTRAPATHS := "${THISDIR}/${PN}" + +SRC_URI += "file://libffi_armeb_be8.patch" -- cgit v1.2.3