summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-03-15 10:55:10 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-03-17 10:33:09 +1000
commit2d638fc37b0dbf28e5c826f74f68ada83a8c3e2b (patch)
treeba794c602096532af9a6010ae22cdaa6195dd0ff
parent477f922fb07eea629f16c55b0a022e836ede6d41 (diff)
Force alignment with sizeof(Atom) for XIButtonClassInfo
The memory layout of an XIButtonClassInfo is [struct XIButtonClassInfo][mask][labels] With the mask being currently 4-byte aligned and labels a list of Atoms. On LP64, Atoms are 8 byte, leading to unaligned access for some mask lengths. Force the alignment to be sizeof(Atom). Reported-by: Christian Weisgerber <naddy@mips.inka.de> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Tested-by: Christian Weisgerber <naddy@mips.inka.de> Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--src/XExtInt.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/XExtInt.c b/src/XExtInt.c
index 5a1bca6..d1451cc 100644
--- a/src/XExtInt.c
+++ b/src/XExtInt.c
@@ -1028,7 +1028,9 @@ sizeDeviceClassType(int type, int num_elements)
case XIButtonClass:
l = sizeof(XIButtonClassInfo);
l += num_elements * sizeof(Atom);
- l += ((((num_elements + 7)/8) + 3)/4) * 4;
+ /* Force mask alignment with longs to avoid
+ * unaligned access when accessing the atoms. */
+ l += ((((num_elements + 7)/8) + 3)/4) * sizeof(Atom);
break;
case XIKeyClass:
l = sizeof(XIKeyClassInfo);
@@ -1121,12 +1123,16 @@ copyDeviceChangedEvent(XGenericEventCookie *in_cookie,
{
case XIButtonClass:
{
+ int size;
XIButtonClassInfo *bin, *bout;
bin = (XIButtonClassInfo*)any;
bout = next_block(&ptr, sizeof(XIButtonClass));
*bout = *bin;
- bout->state.mask = next_block(&ptr, bout->state.mask_len);
+ /* Force mask alignment with longs to avoid unaligned
+ * access when accessing the atoms. */
+ size = bout->state.mask_len/4 * sizeof(Atom);
+ bout->state.mask = next_block(&ptr, size);
memcpy(bout->state.mask, bin->state.mask,
bout->state.mask_len);
@@ -1474,14 +1480,18 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int nclasses)
XIButtonClassInfo *cls_lib;
xXIButtonInfo *cls_wire;
uint32_t *atoms;
+ int size;
int j;
cls_lib = next_block(&ptr_lib, sizeof(XIButtonClassInfo));
cls_wire = (xXIButtonInfo*)any_wire;
cls_lib->num_buttons = cls_wire->num_buttons;
- cls_lib->state.mask_len = ((((cls_wire->num_buttons + 7)/8) + 3)/4) * 4;
- cls_lib->state.mask = next_block(&ptr_lib, cls_lib->state.mask_len);
+ size = ((((cls_wire->num_buttons + 7)/8) + 3)/4);
+ cls_lib->state.mask_len = size * 4;
+ /* Force mask alignment with longs to avoid unaligned
+ * access when accessing the atoms. */
+ cls_lib->state.mask = next_block(&ptr_lib, size * sizeof(Atom));
memcpy(cls_lib->state.mask, &cls_wire[1],
cls_lib->state.mask_len);