XIValuatorClassInfo might have an address of 4 bytes modulo 8, while it contains a double which needs 8 byte alignment. This is fixed by adding extra padding before instances of this structure in size_classes and copy_classes.
Padding added by other commits probably prevents unaligned accesses on all architectures with 8 byte longs and 8 byte double alignment requirement, so this error occurs only on ABIs with 4 byte longs and 8 byte required double alignment. I don't know any other such ABI than MIPS N32, so the change uses conditionals on ABI-specific macro. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=38331 Signed-off-by: Michał Masłowski <[email protected]> --- src/XExtInt.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/src/XExtInt.c b/src/XExtInt.c index b12886d..297b95c 100644 --- a/src/XExtInt.c +++ b/src/XExtInt.c @@ -1495,6 +1495,11 @@ size_classes(xXIAnyInfo* from, int nclasses) ((xXIKeyInfo*)any_wire)->num_keycodes); break; case XIValuatorClass: +#ifdef _ABIN32 + /* Avoid a bus error on MIPS N32. */ + if (len % 8 != 0) + len += 8 - len % 8; +#endif l = sizeDeviceClassType(XIValuatorClass, 0); break; case XIScrollClass: @@ -1598,6 +1603,14 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) XIValuatorClassInfo *cls_lib; xXIValuatorInfo *cls_wire; +#ifdef _ABIN32 + /* On MIPS n32 doubles must be 8 byte aligned, but + longs take 4 bytes, so ptr_lib might be + unaligned, causing a bus error when setting + cls_lib->min. */ + if (((size_t) ptr_lib) % 8 != 0) + *(unsigned char**) &ptr_lib += 8 - ((size_t) ptr_lib) % 8; +#endif cls_lib = next_block(&ptr_lib, sizeof(XIValuatorClassInfo)); cls_wire = (xXIValuatorInfo*)any_wire; -- 1.7.9.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
