Bug#653308: value_from_ffi_type: broken on 64bit big endian
Philipp Kern
pkern at debian.org
Mon Dec 26 17:48:26 UTC 2011
Source: glib2.0
Version: 2.30.2-4
Severity: important
Tags: patch
User: debian-s390 at lists.debian.org
Usertags: s390x
gobject/gclosure.c:value_from_ffi_type in sid does conversions that are unsafe
on big endian architectures and cause breakage at least on 64bit big endian
architectures (such as s390x, sparc64 and ppc64). For G_TYPE_BOOLEAN you'd
get the first machine word (zeros) instead of the one in the second word
(MSB first). Hence glib-networking's testsuite broke.
This was already fixed upstream, they replaced the function with this[1]:
static void
value_from_ffi_type (GValue *gvalue, gpointer *value)
{
ffi_arg *int_val = (ffi_arg*) value;
switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
{
case G_TYPE_INT:
g_value_set_int (gvalue, (gint) *int_val);
break;
case G_TYPE_FLOAT:
g_value_set_float (gvalue, *(gfloat*)value);
break;
case G_TYPE_DOUBLE:
g_value_set_double (gvalue, *(gdouble*)value);
break;
case G_TYPE_BOOLEAN:
g_value_set_boolean (gvalue, (gboolean) *int_val);
break;
case G_TYPE_STRING:
g_value_set_string (gvalue, *(gchar**)value);
break;
case G_TYPE_CHAR:
g_value_set_schar (gvalue, (gint8) *int_val);
break;
case G_TYPE_UCHAR:
g_value_set_uchar (gvalue, (guchar) *int_val);
break;
case G_TYPE_UINT:
g_value_set_uint (gvalue, (guint) *int_val);
break;
case G_TYPE_POINTER:
g_value_set_pointer (gvalue, *(gpointer*)value);
break;
case G_TYPE_LONG:
g_value_set_long (gvalue, (glong) *int_val);
break;
case G_TYPE_ULONG:
g_value_set_ulong (gvalue, (gulong) *int_val);
break;
case G_TYPE_INT64:
g_value_set_int64 (gvalue, (gint64) *int_val);
break;
case G_TYPE_UINT64:
g_value_set_uint64 (gvalue, (guint64) *int_val);
break;
case G_TYPE_BOXED:
g_value_set_boxed (gvalue, *(gpointer*)value);
break;
case G_TYPE_ENUM:
g_value_set_enum (gvalue, (gint) *int_val);
break;
case G_TYPE_FLAGS:
g_value_set_flags (gvalue, (guint) *int_val);
break;
case G_TYPE_PARAM:
g_value_set_param (gvalue, *(gpointer*)value);
break;
case G_TYPE_OBJECT:
g_value_set_object (gvalue, *(gpointer*)value);
break;
default:
g_warning ("value_from_ffi_type: Unsupported fundamental type: %s",
g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
}
}
At least for gboolean that looks much more sane and solves the problem. Given
the fact that a bunch of the other cases were also problematic, I'd suggest
replacing that function with the one above. I was told that FFI support is
pretty new, I don't know if there are more big endian issues lingering around.
The testsuite has a bunch of issues too.
If that could be fixed timely, that would be cool. (As long as it doesn't
break anything, but the old code looked obviously wrong.) It blocks a lot of
GNOME stuff being built on s390x, because glib-networking aborts on testsuite
failures.
Kind regards
Philipp Kern
[1] http://git.gnome.org/browse/glib/tree/gobject/gclosure.c#n1032
More information about the pkg-gnome-maintainers
mailing list