Package: lcms2
Version: 2.6-1
Severity: important
Tags: patch upstream

colord fails to build from source on both mips/mipsel due to an
unaligned access (SIGBUS):

https://buildd.debian.org/status/fetch.php?pkg=colord&arch=mips&ver=1.2.0-3&stamp=1401475533
https://buildd.debian.org/status/fetch.php?pkg=colord&arch=mipsel&ver=1.2.0-3&stamp=1401374635

The MIPS architecture requires that load/stores are done with an
alignment corresponding to the type, so even if it is a 32-bit
architecture accesses to double values (8-bytes) require a 64-bit
alignment.

Currently the lcms2 memory allocator only guarantee an alignment
corresponding the size of (void *). Since version 2.6, lcms2 now also
store double values (called cmsFloat64Number), causing some random
issues on mips/mipsel, depending on how lucky we are about the
alignement. SPARC is likely to also be affected, as the same
alignment requirement applies.


There are two ways of fixing that, either increasing the alignment to
64-bit on mips/mipsel/sparc:

--- a/src/lcms2_internal.h
+++ b/src/lcms2_internal.h
@@ -56,8 +56,13 @@
 // Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
 #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & 
~(sizeof(cmsUInt32Number)-1))
 
-// Alignment to memory pointer
-#define _cmsALIGNMEM(x)  (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
+// Alignment to maximum required alignment
+// On MIPS and SPARC, access to double values need to be 8-bytes aligned
+#if defined(__mips__) || defined(__sparc__)
+#   define _cmsALIGNMEM(x)  ((x + 7) & ~7)
+#else
+#   define _cmsALIGNMEM(x)  (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 
1))
+#endif
 
 // Maximum encodeable values in floating point
 #define MAX_ENCODEABLE_XYZ  (1.0 + 32767.0/32768.0)



As it seems storing 64-bit values is not the common case, the other
alternative is to tell GCC that the stored double values are aligned
to (void *), so that it generate code to do unaligned access if needed.
This can be specified independently of the architecture as this is
always true, and might even help GCC to generate better code. This is
what the patch below does:

--- a/src/lcms2_internal.h
+++ b/src/lcms2_internal.h
@@ -479,11 +479,13 @@
                             const struct _cmsContext_struct* src);
 
 // Container for adaptation state -- not a plug-in
+// The chunks are only guaranteed to be aligned to void *, tell that to the
+// compiler so that it can generate unaligned access instructions if needed.
 typedef struct {
     
     cmsFloat64Number  AdaptationState;
 
-} _cmsAdaptationStateChunkType;
+} _cmsAdaptationStateChunkType __attribute__ ((__aligned__(__alignof__(void 
*))));
 
 // The global Context0 storage for adaptation state
 extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;


-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: mipsel (mips64)

Kernel: Linux 3.2.0-4-5kc-malta
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to