Dear Maintainer, I've prepared an NMU versioned as 2:1.4.5-1.1. The package is available at [1] and the debdiff is attached.
On 04/04/12 11:22, Sebastian Ramacher wrote: > I've backported c1a5a70b51f12dedf354102217c7cd4247ed3a4b to 1.4.5. The patch > is > attached. In addition to c1a5a70b51f12dedf354102217c7cd4247ed3a4b upstream's 8436c920953f288aea2d6d5f370f8eaaaef82d97 [2] is also required. Otherwise libxi fails to work on ppc since c1a5a70b51f12dedf354102217c7cd4247ed3a4b introduced a regression: # xinput list --long ⎡ Virtual core pointer id=2 [master pointer (3)] Reporting 3 classes: Class originated from: 2 Buttons supported: 10 X Error of failed request: BadAtom (invalid Atom parameter) Major opcode of failed request: 17 (X_GetAtomName) Atom id in failed request: 0x2000b Serial number of failed request: 23 Current serial number in output stream: 23 Button labels: Button Middle Button Right Button Wheel Up Button Wheel Down Button Horiz Wheel Left Button Horiz Wheel Right None None None 8436c920953f288aea2d6d5f370f8eaaaef82d97 is also included in the NMU. [1] http://mentors.debian.net/debian/pool/main/libx/libxi/libxi_1.4.5-1.1.dsc [2] http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=8436c920953f288aea2d6d5f370f8eaaaef82d97 -- Sebastian Ramacher
diff -u libxi-1.4.5/debian/changelog libxi-1.4.5/debian/changelog --- libxi-1.4.5/debian/changelog +++ libxi-1.4.5/debian/changelog @@ -1,3 +1,12 @@ +libxi (2:1.4.5-1.1) unstable; urgency=low + + * Non-maintainer upload. + * Backport fixes from upstream: + - Fix bus error on MIPS N32 (Closes: #636920) + - Fix wrong button label and mask copy on OS X. + + -- Sebastian Ramacher <s.ramac...@gmx.at> Sat, 07 Apr 2012 16:55:42 +0200 + libxi (2:1.4.5-1) unstable; urgency=low * New upstream release. diff -u libxi-1.4.5/debian/patches/series libxi-1.4.5/debian/patches/series --- libxi-1.4.5/debian/patches/series +++ libxi-1.4.5/debian/patches/series @@ -1 +1 @@ -# placeholder. +c1a5a70b-1.4.5.patch only in patch2: unchanged: --- libxi-1.4.5.orig/debian/patches/c1a5a70b-1.4.5.patch +++ libxi-1.4.5/debian/patches/c1a5a70b-1.4.5.patch @@ -0,0 +1,258 @@ +Description: Fix bus error on MIPS N32. + XIValuatorClassInfo might have an address of 4 bytes modulo 8, while it + contains doubles which need 8 byte alignment. This is fixed by adding extra + padding after each structure or array in sizeDeviceClassType and adding + helper functions to determine sizes and padding only in one place. + . + This is upstream's c1a5a70b51f12dedf354102217c7cd4247ed3a4b backported to + 1.4.5 and also includes 8436c920953f288aea2d6d5f370f8eaaaef82d97 to fix the + regression introduced in c1a5a70b51f12dedf354102217c7cd4247ed3a4b. +Origin: + http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=c1a5a70b, + http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=8436c920 +Last-Update: 2012-04-07 +Bug-Debian: http://bugs.debian.org/636920 + +diff --git a/src/XExtInt.c b/src/XExtInt.c +index 63afb8f..bf051f9 100644 +--- a/src/XExtInt.c ++++ b/src/XExtInt.c +@@ -1012,6 +1012,55 @@ sizeDeviceEvent(int buttons_len, int valuators_len, + return len; + } + ++/* 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 int ++pad_to_double(int size) ++{ ++#if !defined(__i386__) && !defined(__sh__) ++ if (size % sizeof(double) != 0) ++ size += sizeof(double) - size % sizeof(double); ++#endif ++ return size; ++} ++ ++/** ++ * Set structure and atoms to size in bytes of XIButtonClassInfo, its ++ * button state mask and labels array. ++ */ ++static void ++sizeXIButtonClassType(int num_buttons, int* structure, int* state, int* atoms) ++{ ++ int size; ++ int labels; ++ ++ *structure = pad_to_double(sizeof(XIButtonClassInfo)); ++ size = ((((num_buttons + 7)/8) + 3)/4); ++ ++ /* Force mask alignment with longs to avoid unaligned ++ * access when accessing the atoms. */ ++ *state = pad_to_double(size * 4); ++ labels = num_buttons * sizeof(Atom); ++ ++ /* Force mask alignment with longs to avoid ++ * unaligned access when accessing the atoms. */ ++ labels += ((((num_buttons + 7)/8) + 3)/4) * sizeof(Atom); ++ *atoms = pad_to_double(labels); ++} ++ ++/** ++ * Set structure and keycodes to size in bytes of XIKeyClassInfo and ++ * its keycodes array. ++ */ ++static void ++sizeXIKeyClassType(int num_keycodes, int* structure, int* keycodes) ++{ ++ *structure = pad_to_double(sizeof(XIKeyClassInfo)); ++ *keycodes = pad_to_double(num_keycodes * sizeof(int)); ++} ++ + /** + * Return the size in bytes required to store the matching class type + * num_elements is num_buttons for XIButtonClass or num_keycodes for +@@ -1023,21 +1072,21 @@ static int + sizeDeviceClassType(int type, int num_elements) + { + int l = 0; ++ int extra1 = 0; ++ int extra2 = 0; + switch(type) + { + case XIButtonClass: +- l = sizeof(XIButtonClassInfo); +- l += num_elements * sizeof(Atom); +- /* Force mask alignment with longs to avoid +- * unaligned access when accessing the atoms. */ +- l += ((((num_elements + 7)/8) + 3)/4) * sizeof(Atom); ++ sizeXIButtonClassType(num_elements, &l, &extra1, &extra2); ++ l += extra1 + extra2; + break; + case XIKeyClass: +- l = sizeof(XIKeyClassInfo); +- l += num_elements * sizeof(int); ++ sizeXIKeyClassType(num_elements, &l, &extra1); ++ l += extra1; + break; + case XIValuatorClass: + l = sizeof(XIValuatorClassInfo); ++ l = pad_to_double(sizeof(XIValuatorClassInfo)); + break; + default: + printf("sizeDeviceClassType: unknown type %d\n", type); +@@ -1123,20 +1172,21 @@ copyDeviceChangedEvent(XGenericEventCookie *in_cookie, + { + case XIButtonClass: + { +- int size; ++ int struct_size; ++ int state_size; ++ int labels_size; + XIButtonClassInfo *bin, *bout; + bin = (XIButtonClassInfo*)any; +- bout = next_block(&ptr, sizeof(XIButtonClass)); ++ sizeXIButtonClassType(bin->num_buttons, &struct_size, ++ &state_size, &labels_size); ++ bout = next_block(&ptr, struct_size); + + *bout = *bin; +- /* 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); ++ bout->state.mask = next_block(&ptr, state_size); + memcpy(bout->state.mask, bin->state.mask, + bout->state.mask_len); + +- bout->labels = next_block(&ptr, bout->num_buttons * sizeof(Atom)); ++ bout->labels = next_block(&ptr, labels_size); + memcpy(bout->labels, bin->labels, bout->num_buttons * sizeof(Atom)); + out->classes[i] = (XIAnyClassInfo*)bout; + break; +@@ -1144,11 +1194,15 @@ copyDeviceChangedEvent(XGenericEventCookie *in_cookie, + case XIKeyClass: + { + XIKeyClassInfo *kin, *kout; ++ int struct_size; ++ int keycodes_size; + kin = (XIKeyClassInfo*)any; ++ sizeXIKeyClassType(kin->num_keycodes, &struct_size, ++ &keycodes_size); + +- kout = next_block(&ptr, sizeof(XIKeyClass)); ++ kout = next_block(&ptr, struct_size); + *kout = *kin; +- kout->keycodes = next_block(&ptr, kout->num_keycodes * sizeof(int)); ++ kout->keycodes = next_block(&ptr, keycodes_size); + memcpy(kout->keycodes, kin->keycodes, kout->num_keycodes * sizeof(int)); + out->classes[i] = (XIAnyClassInfo*)kout; + break; +@@ -1157,7 +1211,8 @@ copyDeviceChangedEvent(XGenericEventCookie *in_cookie, + { + XIValuatorClassInfo *vin, *vout; + vin = (XIValuatorClassInfo*)any; +- vout = next_block(&ptr, sizeof(XIValuatorClass)); ++ vout = next_block(&ptr, ++ sizeDeviceClassType(XIValuatorClass, 0)); + *vout = *vin; + out->classes[i] = (XIAnyClassInfo*)vout; + break; +@@ -1414,7 +1469,8 @@ size_classes(xXIAnyInfo* from, int nclasses) + xXIAnyInfo *any_wire; + char *ptr_wire; + +- len = nclasses * sizeof(XIAnyClassInfo*); /* len for to->classes */ ++ /* len for to->classes */ ++ len = pad_to_double(nclasses * sizeof(XIAnyClassInfo*)); + ptr_wire = (char*)from; + for (i = 0; i < nclasses; i++) + { +@@ -1463,7 +1519,8 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) + + ptr_wire = (char*)from; + ptr_lib = to->classes; +- to->classes = next_block(&ptr_lib, (*nclasses) * sizeof(XIAnyClassInfo*)); ++ to->classes = next_block(&ptr_lib, ++ pad_to_double((*nclasses) * sizeof(XIAnyClassInfo*))); + memset(to->classes, 0, (*nclasses) * sizeof(XIAnyClassInfo*)); + len = 0; /* count wire length */ + +@@ -1479,25 +1536,33 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) + XIButtonClassInfo *cls_lib; + xXIButtonInfo *cls_wire; + uint32_t *atoms; +- int size; + int j; ++ int struct_size; ++ int state_size; ++ int labels_size; ++ int wire_mask_size; + +- cls_lib = next_block(&ptr_lib, sizeof(XIButtonClassInfo)); + cls_wire = (xXIButtonInfo*)any_wire; ++ sizeXIButtonClassType(cls_wire->num_buttons, ++ &struct_size, &state_size, ++ &labels_size); ++ cls_lib = next_block(&ptr_lib, struct_size); ++ wire_mask_size = ((cls_wire->num_buttons + 7)/8 + 3)/4 * 4; + + cls_lib->type = cls_wire->type; + cls_lib->sourceid = cls_wire->sourceid; + cls_lib->num_buttons = cls_wire->num_buttons; +- 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)); ++ cls_lib->state.mask_len = state_size; ++ cls_lib->state.mask = next_block(&ptr_lib, state_size); + memcpy(cls_lib->state.mask, &cls_wire[1], +- cls_lib->state.mask_len); ++ wire_mask_size); ++ if (state_size != wire_mask_size) ++ memset(&cls_lib->state.mask[wire_mask_size], 0, ++ state_size - wire_mask_size); ++ ++ cls_lib->labels = next_block(&ptr_lib, labels_size); + +- cls_lib->labels = next_block(&ptr_lib, cls_lib->num_buttons * sizeof(Atom)); +- atoms =(uint32_t*)((char*)&cls_wire[1] + cls_lib->state.mask_len); ++ atoms =(uint32_t*)((char*)&cls_wire[1] + wire_mask_size); + for (j = 0; j < cls_lib->num_buttons; j++) + cls_lib->labels[j] = *atoms++; + +@@ -1508,15 +1573,18 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) + { + XIKeyClassInfo *cls_lib; + xXIKeyInfo *cls_wire; ++ int struct_size; ++ int keycodes_size; + +- cls_lib = next_block(&ptr_lib, sizeof(XIKeyClassInfo)); + cls_wire = (xXIKeyInfo*)any_wire; ++ sizeXIKeyClassType(cls_wire->num_keycodes, ++ &struct_size, &keycodes_size); ++ cls_lib = next_block(&ptr_lib, struct_size); + + cls_lib->type = cls_wire->type; + cls_lib->sourceid = cls_wire->sourceid; + cls_lib->num_keycodes = cls_wire->num_keycodes; +- cls_lib->keycodes = next_block(&ptr_lib, +- cls_lib->num_keycodes * sizeof(int)); ++ cls_lib->keycodes = next_block(&ptr_lib, keycodes_size); + memcpy(cls_lib->keycodes, &cls_wire[1], + cls_lib->num_keycodes); + +@@ -1528,7 +1596,9 @@ copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) + XIValuatorClassInfo *cls_lib; + xXIValuatorInfo *cls_wire; + +- cls_lib = next_block(&ptr_lib, sizeof(XIValuatorClassInfo)); ++ cls_lib = ++ next_block(&ptr_lib, ++ sizeDeviceClassType(XIValuatorClass, 0)); + cls_wire = (xXIValuatorInfo*)any_wire; + + cls_lib->type = cls_wire->type;
signature.asc
Description: OpenPGP digital signature