Package: ocaml-ctypes
Version: 0.7.0-1
Severity: important
Tags: sid + patch + fixed-upstream
Justification: FTBFS
User: [email protected]
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;
}