XIValuatorClassInfo and XIScrollClassInfo might have an address of 4 bytes modulo 8, while they contain doubles which needs 8 byte alignment. This is fixed by adding extra padding before instances of these structure in size_classes and copy_classes.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=38331 Signed-off-by: Michał Masłowski <[email protected]> --- src/XExtInt.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/src/XExtInt.c b/src/XExtInt.c index b12886d..b537730 100644 --- a/src/XExtInt.c +++ b/src/XExtInt.c @@ -1471,6 +1471,30 @@ wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie) return 1; } +/* Return the size with added padding so next element would be + double-aligned unless the architecture is known to allow unaligned + data accesses. Not doing this can cause a bus error on + MIPS N32. */ +static size_t +pad_to_double(size_t size) +{ +#if !defined(__i386__) && !defined(__sh__) + if (size % sizeof(double) != 0) + size += sizeof(double) - size % sizeof(double); +#endif + return size; +} + +static void* +pad_ptr_to_double(void* ptr) +{ +#if !defined(__i386__) && !defined(__sh__) + if (((size_t) ptr) % sizeof(double) != 0) + *(unsigned char**) &ptr += sizeof(double) - ((size_t) ptr) % sizeof(double); +#endif + return ptr; +} + _X_HIDDEN int size_classes(xXIAnyInfo* from, int nclasses) { @@ -1495,9 +1519,11 @@ size_classes(xXIAnyInfo* from, int nclasses) ((xXIKeyInfo*)any_wire)->num_keycodes); break; case XIValuatorClass: + len = pad_to_double(len); l = sizeDeviceClassType(XIValuatorClass, 0); break; case XIScrollClass: + len = pad_to_double(len); l = sizeDeviceClassType(XIScrollClass, 0); break; case XITouchClass: @@ -1598,6 +1624,7 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) XIValuatorClassInfo *cls_lib; xXIValuatorInfo *cls_wire; + ptr_lib = pad_ptr_to_double(ptr_lib); cls_lib = next_block(&ptr_lib, sizeof(XIValuatorClassInfo)); cls_wire = (xXIValuatorInfo*)any_wire; @@ -1620,6 +1647,7 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) XIScrollClassInfo *cls_lib; xXIScrollInfo *cls_wire; + ptr_lib = pad_ptr_to_double(ptr_lib); cls_lib = next_block(&ptr_lib, sizeof(XIScrollClassInfo)); cls_wire = (xXIScrollInfo*)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
