[PATCH libXi] Fix bus error on MIPS N32 for bug #38331.

Michał Masłowski mtjm at mtjm.eu
Mon Feb 20 11:09:30 PST 2012


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 <mtjm at mtjm.eu>
---
 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



More information about the xorg-devel mailing list