Package: ocaml-ctypes Version: 0.7.0-1 Severity: important Tags: sid + patch + fixed-upstream Justification: FTBFS User: debian-m...@lists.debian.org Usertags: mips-patch Forwarded: https://github.com/ocamllabs/ocaml-ctypes/issues/441<https://github.com/ocamllabs/ocaml-ctypes/issues/441#issuecomment-245922709>
Hi, Package ocaml-ctypes FTBFS for mips64el on testing with following error: > ============================================================================= > Error: Higher-order tests:1:test_higher_order_basic (stubs). > > File "/«PKGBUILDDIR»/_build/oUnit-Higher-order tests-mipsel-sil-01#00.log", > line 26, characters 1-1: > Error: Higher-order tests:1:test_higher_order_basic (stubs) (in the log). > > (Program not linked with -g, cannot print stack backtrace) > > not equal > ------------------------------------------------------------------------------ > ============================================================================== > Error: Higher-order tests:0:test_higher_order_basic (foreign). > > File "/«PKGBUILDDIR»/_build/oUnit-Higher-order tests-mipsel-sil-01#00.log", > line 20, characters 1-1: > Error: Higher-order tests:0:test_higher_order_basic (foreign) (in the log). > > (Program not linked with -g, cannot print stack backtrace) > > not equal > ------------------------------------------------------------------------------ Full log: https://buildd.debian.org/status/fetch.php?pkg=ocaml-ctypes&arch=mips64el&ver=0.7.0-1&stamp=1470056946 This bug was reported and fixed upstream: https://github.com/ocamllabs/ocaml-ctypes/issues/441<https://github.com/ocamllabs/ocaml-ctypes/issues/441#issuecomment-245922709> The tests are failing because there is a problem with integers smaller than word-size. They was always zero-extended, never sign-extended. The attached patch is a back-ported pull request (https://github.com/ocamllabs/ocaml-ctypes/pull/456) created by Andreas Hauptmann (fdopen) for this bug. With this patch I was able to build ocaml-ctype successfully for mips64el. Thanks, Daniel
--- ocaml-ctypes-0.7.0.orig/src/ctypes-foreign-base/ffi_call_stubs.c +++ ocaml-ctypes-0.7.0/src/ctypes-foreign-base/ffi_call_stubs.c @@ -256,9 +256,11 @@ value ctypes_add_argument(value callspec CAMLreturn(Val_int(offset)); } -static int ffi_return_type_promotes(ffi_type *f) +static int ffi_return_type_adjustment(ffi_type *f) { - /* libffi promotes integer return types that are smaller than a word */ +#ifdef ARCH_BIG_ENDIAN + /* An adjustment is needed (on bigendian systems) for integer types + less than the size of a word */ if (f->size < sizeof(ffi_arg)) { switch (f->type) { case FFI_TYPE_INT: @@ -270,21 +272,10 @@ static int ffi_return_type_promotes(ffi_ case FFI_TYPE_SINT32: case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: - return 1; + return sizeof(ffi_arg) - f->size; default: break; } } - return 0; -} - -static int ffi_return_type_adjustment(ffi_type *f) -{ -#ifdef ARCH_BIG_ENDIAN - /* An adjustment is needed (on bigendian systems) for integer types - less than the size of a word */ - if (ffi_return_type_promotes(f)) { - return sizeof(ffi_arg) - f->size; - } #endif return 0; } @@ -471,13 +462,51 @@ static void callback_handler_with_lock(f /* now store the return value */ assert (Tag_val(boxedfn) == Done); - if (ffi_return_type_promotes(cif->rtype)) { - *(ffi_arg *)ret = 0; - } - - argptr = CTYPES_FROM_PTR(ret + ffi_return_type_adjustment(cif->rtype)); + argptr = CTYPES_FROM_PTR(ret); caml_callback(Field(boxedfn, 0), argptr); + /* workaround for libffi api: small integers must be promoted to + * full word size (sign/zero extended) */ + if (cif->rtype->size < sizeof(ffi_arg)) { + int do_nothing = 0; + ffi_arg x; + switch (cif->rtype->type) { + case FFI_TYPE_INT: + x = *(int*)ret; + break; + case FFI_TYPE_UINT8: + x = *(uint8_t*)ret; + break; + case FFI_TYPE_SINT8: + x = *(int8_t*)ret; + break; + case FFI_TYPE_UINT16: + x = *(uint16_t*)ret; + break; + case FFI_TYPE_SINT16: + x = *(int16_t*)ret; + break; + case FFI_TYPE_UINT32: + x = *(uint32_t*)ret; + break; + case FFI_TYPE_SINT32: + x = *(int32_t*)ret; + break; + case FFI_TYPE_UINT64: + x = *(uint64_t*)ret; + break; + case FFI_TYPE_SINT64: + x = *(int64_t*)ret; + break; + default: + do_nothing = 1; + break; + } + if ( do_nothing == 0 ) { + *(ffi_arg*)ret = x; + } + } + CAMLreturn0; }