diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-03-15 10:55:10 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-03-17 10:33:09 +1000 |
commit | 2d638fc37b0dbf28e5c826f74f68ada83a8c3e2b (patch) | |
tree | ba794c602096532af9a6010ae22cdaa6195dd0ff | |
parent | 477f922fb07eea629f16c55b0a022e836ede6d41 (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.c | 18 |
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); |