[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