[PATCH libXi] Fix bus error on MIPS N32 for bug #38331.
Michał Masłowski
mtjm at mtjm.eu
Mon Feb 20 14:47:33 PST 2012
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 <mtjm at mtjm.eu>
---
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
More information about the xorg-devel
mailing list