Package: htslib
Version: 0.2.0~rc3-1
Tags: sid patch
Severity: important
Justification: FTBFS
User: debian-mips-dev-disc...@lists.alioth.debian.org
Usertags: mips-patch


While trying to build htslib on mips/mipsel, build fails on testing.

On mips, package fails with the following error:

>  ./compare_sam.pl xx#unsorted.sam xx#unsorted.tmp.cram.sam_
>  ./test_view -t xx.fa -C xx#unsorted.tmp.bam > xx#unsorted.tmp.bam.cram
>  ./test_view -b -D xx#unsorted.tmp.bam.cram > xx#unsorted.tmp.bam.cram.bam
>  ./test_view xx#unsorted.tmp.bam.cram.bam > xx#unsorted.tmp.bam.cram.bam.sam_
>  ./compare_sam.pl xx#unsorted.sam xx#unsorted.tmp.bam.cram.bam.sam_
>
>Successes 235
>
>Failures  5
>make[2]: *** [test] Error 1
>make[2]: Leaving directory `/«PKGBUILDDIR»'
>dh_auto_test: make -j1 test returned exit code 2
>make[1]: *** [override_dh_auto_test] Error 2
>make[1]: Leaving directory `/«PKGBUILDDIR»'
>make: *** [build-arch] Error 2


The reason for that are endianness related issues:
 - system endianness is not detected properly
 - function which converts multibyte data from big endian byte to little
endian byte order (and vice versa) has errors (this was partially fixed
in latest upstream release).

This is fixed in '01-fix-endianness.patch'.
After applying it, build fails with error:

>  ./compare_sam.pl xx#unsorted.sam xx#unsorted.tmp.cram.sam_
>  ./test_view -t xx.fa -C xx#unsorted.tmp.bam > xx#unsorted.tmp.bam.cram
>  ./test_view -b -D xx#unsorted.tmp.bam.cram > xx#unsorted.tmp.bam.cram.bam
>  ./test_view xx#unsorted.tmp.bam.cram.bam > xx#unsorted.tmp.bam.cram.bam.sam_
>  ./compare_sam.pl xx#unsorted.sam xx#unsorted.tmp.bam.cram.bam.sam_
>make[2]: *** [test] Error 1
>
>Successes 234
>
>Failures  6
>make[2]: Leaving directory `/«PKGBUILDDIR»'
>dh_auto_test: make -j1 test returned exit code 2
>make[1]: *** [override_dh_auto_test] Error 2
>make[1]: Leaving directory `/«PKGBUILDDIR»'
>make: *** [build-arch] Error 2

The same error appears on mipsel.

Reason for this is that unaligned memory access is not handled well
for achitectures that don't allow unaligned access, which causes bus errors
on both mips and mipsel.
This is fixed in '02-fix-alignment.patch'.


With these patches applied I have successfully built htslib on mips/mipsel.

Could you please consider including this patch?

Best regards,
Aleksandar Zlicic
--- a/cram/cram_encode.c
+++ b/cram/cram_encode.c
@@ -1858,6 +1858,12 @@
     return rg;
 }
 
+static inline int is_big_endian(){
+    int x = 0x01;
+    char *c = (char*)&x;
+    return (c[0] != 0x01);
+}
+
 /*
  * Encodes auxiliary data. Largely duplicated from above, but done so to
  * keep it simple and avoid a myriad of version ifs.
@@ -1949,10 +1955,21 @@
 
 	case 'B': {
 	    int type = aux[3], blen;
-	    uint32_t count = (uint32_t)((((unsigned char *)aux)[4]<< 0) +
+            uint32_t count;
+            if(is_big_endian())
+            {
+		count = (uint32_t)((((unsigned char *)aux)[7]<< 0) +
+					(((unsigned char *)aux)[6]<< 8) +
+					(((unsigned char *)aux)[5]<<16) +
+					(((unsigned char *)aux)[4]<<24));
+            }
+            else
+            {
+	        count = (uint32_t)((((unsigned char *)aux)[4]<< 0) +
 					(((unsigned char *)aux)[5]<< 8) +
 					(((unsigned char *)aux)[6]<<16) +
 					(((unsigned char *)aux)[7]<<24));
+            }
 	    // skip TN field
 	    aux+=3;
 
--- a/cram/os.h
+++ b/cram/os.h
@@ -88,8 +88,15 @@
  * processor type too.
  */
 
-/* Set by autoconf */
-#define SP_LITTLE_ENDIAN
+#if !defined(SP_BIG_ENDIAN) && !defined(SP_LITTLE_ENDIAN)
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+#   define SP_BIG_ENDIAN
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#   define SP_LITTLE_ENDIAN
+#endif
+
+#endif
 
 /* Mac FAT binaries or unknown. Auto detect based on CPU type */
 #if !defined(SP_BIG_ENDIAN) && !defined(SP_LITTLE_ENDIAN)
--- a/sam.c
+++ b/sam.c
@@ -216,7 +216,12 @@
 	else return 0;
 }
 
-static void swap_data(const bam1_core_t *c, int l_data, uint8_t *data)
+typedef enum swap_data_rw {
+        SWAP_DATA_READ,
+        SWAP_DATA_WRITE
+}swap_data_rw_t;
+
+static void swap_data(const bam1_core_t *c, int l_data, uint8_t *data, swap_data_rw_t rw_mode)
 {
 	uint8_t *s;
 	uint32_t *cigar = (uint32_t*)(data + c->l_qname);
@@ -234,15 +239,23 @@
 		else if (type == 'Z' || type == 'H') { while (*s) ++s; ++s; }
 		else if (type == 'B') {
 			int32_t n, Bsize = aux_type2size(*s);
+			if(SWAP_DATA_READ == rw_mode)
+			{
+				ed_swap_4p(s+1);
+			}
 			memcpy(&n, s + 1, 4);
 			if (Bsize == 2) {
-				for (i = 0; i < n; i += 2)
+				for (i = 0; i < n*Bsize; i += 2)
 					ed_swap_2p(s + 5 + i);
 			} else if (Bsize == 4) {
-				for (i = 0; i < n; i += 4)
+				for (i = 0; i < n*Bsize; i += 4)
 					ed_swap_4p(s + 5 + i);
 			}
-			ed_swap_4p(s+1); 
+			if(SWAP_DATA_WRITE == rw_mode)
+			{
+				ed_swap_4p(s+1);
+			}
+			s += (4 + Bsize * n + 1);
 		}
 	}
 }
@@ -274,7 +287,7 @@
 	}
 	if (bgzf_read(fp, b->data, b->l_data) != b->l_data) return -4;
 	//b->l_aux = b->l_data - c->n_cigar * 4 - c->l_qname - c->l_qseq - (c->l_qseq+1)/2;
-	if (fp->is_be) swap_data(c, b->l_data, b->data);
+	if (fp->is_be) swap_data(c, b->l_data, b->data, SWAP_DATA_READ);
 	return 4 + block_len;
 }
 
@@ -296,11 +309,11 @@
 		for (i = 0; i < 8; ++i) ed_swap_4p(x + i);
 		y = block_len;
 		bgzf_write(fp, ed_swap_4p(&y), 4);
-		swap_data(c, b->l_data, b->data);
+		swap_data(c, b->l_data, b->data, SWAP_DATA_WRITE);
 	} else bgzf_write(fp, &block_len, 4);
 	bgzf_write(fp, x, 32);
 	bgzf_write(fp, b->data, b->l_data);
-	if (fp->is_be) swap_data(c, b->l_data, b->data);
+	if (fp->is_be) swap_data(c, b->l_data, b->data, SWAP_DATA_WRITE);
 	return 4 + block_len;
 }
 
--- a/sam.c
+++ b/sam.c
@@ -726,18 +726,69 @@
 	s = bam_get_aux(b); // aux
 	while (s < b->data + b->l_data) {
 		uint8_t type, key[2];
+		uint8_t tmpData[8];
+		int j;
 		key[0] = s[0]; key[1] = s[1];
 		s += 2; type = *s++;
 		kputc('\t', str); kputsn((char*)key, 2, str); kputc(':', str);
 		if (type == 'A') { kputsn("A:", 2, str); kputc(*s, str); ++s; }
 		else if (type == 'C') { kputsn("i:", 2, str); kputw(*s, str); ++s; }
 		else if (type == 'c') { kputsn("i:", 2, str); kputw(*(int8_t*)s, str); ++s; }
+#ifdef ALLOW_UAC
 		else if (type == 'S') { kputsn("i:", 2, str); kputw(*(uint16_t*)s, str); s += 2; }
 		else if (type == 's') { kputsn("i:", 2, str); kputw(*(int16_t*)s, str); s += 2; }
 		else if (type == 'I') { kputsn("i:", 2, str); kputuw(*(uint32_t*)s, str); s += 4; }
 		else if (type == 'i') { kputsn("i:", 2, str); kputw(*(int32_t*)s, str); s += 4; }
 		else if (type == 'f') { ksprintf(str, "f:%g", *(float*)s); s += 4; }
 		else if (type == 'd') { ksprintf(str, "d:%g", *(double*)s); s += 8; }
+#else
+		else if (type == 'S')
+                {
+                    uint16_t *ptmpData = (uint16_t*)&tmpData;
+                    for(j=0;j<2;j++) tmpData[j]=s[j];
+                    kputsn("i:", 2, str);
+                    kputw(*ptmpData, str);
+                    s += 2;
+                }
+		else if (type == 's')
+                {
+                    int16_t *ptmpData = (int16_t*)&tmpData;
+                    for(j=0;j<2;j++) tmpData[j]=s[j];
+                    kputsn("i:", 2, str);
+                    kputw(*ptmpData, str);
+                    s += 2;
+                }
+		else if (type == 'I')
+                {
+                    uint32_t *ptmpData = (uint32_t*)&tmpData;
+                    for(j=0;j<4;j++) tmpData[j]=s[j];
+                    kputsn("i:", 2, str);
+                    kputuw(*ptmpData, str);
+                    s += 4;
+                }
+		else if (type == 'i')
+                {
+                    int32_t *ptmpData = (int32_t*)&tmpData;
+                    for(j=0;j<4;j++) tmpData[j]=s[j];
+                    kputsn("i:", 2, str);
+                    kputw(*ptmpData, str);
+                    s += 4;
+                }
+		else if (type == 'f')
+                {
+                    float *ptmpData = (float*)&tmpData;
+                    for(j=0;j<4;j++) tmpData[j]=s[j];
+                    ksprintf(str, "f:%g", *ptmpData);
+                    s += 4;
+                }
+		else if (type == 'd')
+                {
+                    float *ptmpData = (float*)&tmpData;
+                    for(j=0;j<8;j++) tmpData[j]=s[j];
+                    ksprintf(str, "d:%g", *ptmpData);
+                    s += 8;
+                }
+#endif
 		else if (type == 'Z' || type == 'H') { kputc(type, str); kputc(':', str); while (*s) kputc(*s++, str); ++s; }
 		else if (type == 'B') {
 			uint8_t sub_type = *(s++);
@@ -749,11 +800,49 @@
 				kputc(',', str);
 				if ('c' == sub_type)      { kputw(*(int8_t*)s, str); ++s; }
 				else if ('C' == sub_type) { kputw(*(uint8_t*)s, str); ++s; }
+#ifdef ALLOW_UAC
 				else if ('s' == sub_type) { kputw(*(int16_t*)s, str); s += 2; }
 				else if ('S' == sub_type) { kputw(*(uint16_t*)s, str); s += 2; }
 				else if ('i' == sub_type) { kputw(*(int32_t*)s, str); s += 4; }
 				else if ('I' == sub_type) { kputuw(*(uint32_t*)s, str); s += 4; }
 				else if ('f' == sub_type) { ksprintf(str, "%g", *(float*)s); s += 4; }
+#else
+				else if ('s' == sub_type)
+                                {
+                                    int16_t *ptmpData = (int16_t*)&tmpData;
+                                    for(j=0;j<2;j++) tmpData[j]=s[j];
+                                    kputw(*ptmpData, str);
+                                    s += 2;
+                                }
+				else if ('S' == sub_type)
+                                {
+                                    uint16_t *ptmpData = (uint16_t*)&tmpData;
+                                    for(j=0;j<2;j++) tmpData[j]=s[j];
+                                    kputw(*ptmpData, str);
+                                    s += 2;
+                                }
+				else if ('i' == sub_type)
+                                {
+                                    int32_t *ptmpData = (int32_t*)&tmpData;
+                                    for(j=0;j<4;j++) tmpData[j]=s[j];
+                                    kputw(*ptmpData, str);
+                                    s += 4;
+                                }
+				else if ('I' == sub_type)
+                                {
+                                    uint32_t *ptmpData = (uint32_t *)&tmpData;
+                                    for(j=0;j<4;j++) tmpData[j]=s[j];
+                                    kputuw(*ptmpData, str);
+                                    s += 4;
+                                }
+				else if ('f' == sub_type)
+                                {
+                                    float *ptmpData = (float*)&tmpData;
+                                    for(j=0;j<4;j++) tmpData[j]=s[j];
+                                    ksprintf(str, "%g", *ptmpData);
+                                    s += 4;
+                                }
+#endif
 			}
 		}
 	}
@@ -838,11 +927,21 @@
 {
 	int type;
 	type = *s++;
+#ifdef ALLOW_UAC
 	if (type == 'c') return (int32_t)*(int8_t*)s;
 	else if (type == 'C') return (int32_t)*(uint8_t*)s;
 	else if (type == 's') return (int32_t)*(int16_t*)s;
 	else if (type == 'S') return (int32_t)*(uint16_t*)s;
 	else if (type == 'i' || type == 'I') return *(int32_t*)s;
+#else
+	uint8_t tmpData[4];
+	int j;
+	if (type == 'c') return (int32_t)*(int8_t*)s;
+	else if (type == 'C') return (int32_t)*(uint8_t*)s;
+	else if (type == 's'){ int16_t *ptmpData = (int16_t*)&tmpData; for(j=0;j<2;j++)tmpData[j]=s[j]; return (int32_t)(*ptmpData);}
+	else if (type == 'S'){ uint16_t *ptmpData = (uint16_t*)&tmpData; for(j=0;j<2;j++)tmpData[j]=s[j]; return (int32_t)*ptmpData;}
+	else if (type == 'i' || type == 'I'){ int32_t *ptmpData = (int32_t*)&tmpData; for(j=0;j<4;j++)tmpData[j]=s[j]; return *ptmpData;}
+#endif
 	else return 0;
 }
 
@@ -850,8 +949,25 @@
 {
 	int type;
 	type = *s++;
+#ifdef ALLOW_UAC
 	if (type == 'd') return *(double*)s;
 	else if (type == 'f') return *(float*)s;
+#else
+	uint8_t tmpData[8];
+	int j;
+	if (type == 'd')
+	{
+		double *ptmpData = (double*)&tmpData;
+		for(j=0;j<sizeof(double);j++) tmpData[j]=s[j];
+		return *ptmpData;
+	}
+	else if (type == 'f')
+	{
+		float *ptmpData = (float*)&tmpData;
+		for(j=0;j<sizeof(float);j++) tmpData[j]=s[j];
+		return *ptmpData;
+	}
+#endif
 	else return 0.0;
 }
 
--- a/vcf.c
+++ b/vcf.c
@@ -1435,6 +1435,10 @@
 static inline uint8_t *bcf_unpack_info_core1(uint8_t *ptr, bcf_info_t *info)
 {
     uint8_t *ptr_start = ptr;
+#ifndef ALLOW_UAC
+    uint8_t tmpData[4];
+    int j;
+#endif
     info->key = bcf_dec_typed_int1(ptr, &ptr);
     info->len = bcf_dec_size(ptr, &ptr, &info->type);
     info->vptr = ptr;
@@ -1443,9 +1447,30 @@
     info->v1.i = 0;
     if (info->len == 1) {
         if (info->type == BCF_BT_INT8 || info->type == BCF_BT_CHAR) info->v1.i = *(int8_t*)ptr;
+#ifdef ALLOW_UAC
         else if (info->type == BCF_BT_INT32) info->v1.i = *(int32_t*)ptr;
         else if (info->type == BCF_BT_FLOAT) info->v1.f = *(float*)ptr;
         else if (info->type == BCF_BT_INT16) info->v1.i = *(int16_t*)ptr;
+#else
+        else if (info->type == BCF_BT_INT32)
+        {
+            int32_t *ptmpData = (int32_t*)&tmpData;
+            for(j=0;j<4;j++) tmpData[j]=ptr[j];
+            info->v1.i = *ptmpData;
+        }
+        else if (info->type == BCF_BT_FLOAT)
+        {
+            float *ptmpData = (float*)&tmpData;
+            for(j=0;j<4;j++) tmpData[j]=ptr[j];
+            info->v1.f = *ptmpData;
+        }
+        else if (info->type == BCF_BT_INT16)
+        {
+            int16_t *ptmpData = (int16_t*)&tmpData;
+            for(j=0;j<2;j++) tmpData[j]=ptr[j];
+            info->v1.i = *ptmpData;
+        }
+#endif
     }
     ptr += info->len << bcf_type_shift[info->type];
     info->vptr_len = ptr - info->vptr;
--- a/htslib/hts.h
+++ b/htslib/hts.h
@@ -238,7 +238,17 @@
 }
 static inline void *ed_swap_2p(void *x)
 {
+#ifdef ALLOW_UAC
 	*(uint16_t*)x = ed_swap_2(*(uint16_t*)x);
+#else
+	uint8_t tmpData[2];
+        uint16_t *ptmpData = (uint16_t*)&tmpData;
+	uint8_t *px = (uint8_t*)x;
+	int j;
+	for(j=0;j<2;j++) tmpData[j] = px[j];
+        *ptmpData = ed_swap_2(*ptmpData);
+	for(j=0;j<2;j++) px[j] = tmpData[j];
+#endif
 	return x;
 }
 static inline uint32_t ed_swap_4(uint32_t v)
@@ -248,7 +258,17 @@
 }
 static inline void *ed_swap_4p(void *x)
 {
+#ifdef ALLOW_UAC
 	*(uint32_t*)x = ed_swap_4(*(uint32_t*)x);
+#else
+	uint8_t tmpData[4];
+	uint32_t *ptmpData = (uint32_t*)&tmpData;
+	uint8_t *px = (uint8_t*)x;
+	int j;
+	for(j=0;j<4;j++) tmpData[j] = px[j];
+	*ptmpData = ed_swap_4(*ptmpData);
+	for(j=0;j<4;j++) px[j] = tmpData[j];
+#endif
 	return x;
 }
 static inline uint64_t ed_swap_8(uint64_t v)
@@ -259,7 +279,17 @@
 }
 static inline void *ed_swap_8p(void *x)
 {
+#ifdef ALLOW_UAC
 	*(uint64_t*)x = ed_swap_8(*(uint64_t*)x);
+#else
+	uint8_t tmpData[8];
+	uint64_t *ptmpData = (uint64_t*)&tmpData;
+	uint8_t *px = (uint8_t*)x;
+	int j;
+	for(j=0;j<8;j++) tmpData[j] = px[j];
+	*ptmpData = ed_swap_8(*ptmpData);
+	for(j=0;j<8;j++) px[j] = tmpData[j];
+#endif
 	return x;
 }
 

Reply via email to