I just look at the patch provided by Aleksandar. I believe unaligned access is still possible after applying it.
The reason is that an auto array of uint8_t is still only guaranteed to be 1-byte aligned. These discussions confirm this: http://stackoverflow.com/questions/4009463/alignment-of-char-arrays http://bytes.com/topic/c/answers/811633-alignment-stack-arrays So I updated the patch to fix this issue. Plamen
diff -urN htslib-0.2.0~rc3/htslib/hts.h htslib-0.2.0~rc3.mine/htslib/hts.h --- htslib-0.2.0~rc3/htslib/hts.h 2014-06-26 14:09:17.000000000 +0000 +++ htslib-0.2.0~rc3.mine/htslib/hts.h 2014-06-26 14:22:45.794658401 +0000 @@ -238,7 +238,18 @@ } static inline void *ed_swap_2p(void *x) { +#ifdef ALLOW_UAC *(uint16_t*)x = ed_swap_2(*(uint16_t*)x); +#else + uint16_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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 +259,18 @@ } static inline void *ed_swap_4p(void *x) { +#ifdef ALLOW_UAC *(uint32_t*)x = ed_swap_4(*(uint32_t*)x); +#else + uint32_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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 +281,18 @@ } static inline void *ed_swap_8p(void *x) { +#ifdef ALLOW_UAC *(uint64_t*)x = ed_swap_8(*(uint64_t*)x); +#else + uint64_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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; } diff -urN htslib-0.2.0~rc3/sam.c htslib-0.2.0~rc3.mine/sam.c --- htslib-0.2.0~rc3/sam.c 2014-06-26 14:09:17.000000000 +0000 +++ htslib-0.2.0~rc3.mine/sam.c 2014-06-26 14:23:27.282606547 +0000 @@ -7,6 +7,7 @@ #include "htslib/sam.h" #include "htslib/bgzf.h" #include "cram/cram.h" +#include "cram/os.h" #include "hfile.h" #include "htslib/khash.h" @@ -713,18 +714,70 @@ s = bam_get_aux(b); // aux while (s < b->data + b->l_data) { uint8_t type, key[2]; + uint64_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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++); @@ -736,11 +789,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 } } } @@ -825,11 +916,22 @@ { 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 + uint32_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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; } @@ -837,8 +939,26 @@ { int type; type = *s++; +#ifdef ALLOW_UAC if (type == 'd') return *(double*)s; else if (type == 'f') return *(float*)s; +#else + uint64_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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; } diff -urN htslib-0.2.0~rc3/vcf.c htslib-0.2.0~rc3.mine/vcf.c --- htslib-0.2.0~rc3/vcf.c 2013-10-28 13:03:29.000000000 +0000 +++ htslib-0.2.0~rc3.mine/vcf.c 2014-06-26 14:20:54.834797082 +0000 @@ -10,6 +10,7 @@ #include "htslib/vcf.h" #include "htslib/tbx.h" #include "hfile.h" +#include "cram/os.h" #include "htslib/khash.h" KHASH_MAP_INIT_STR(vdict, bcf_idinfo_t) @@ -1435,6 +1436,11 @@ static inline uint8_t *bcf_unpack_info_core1(uint8_t *ptr, bcf_info_t *info) { uint8_t *ptr_start = ptr; +#ifndef ALLOW_UAC + uint32_t tmpDataBuffer; + uint8_t *tmpData = (uint8_t *)&tmpDataBuffer; + 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 +1449,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;
signature.asc
Description: Digital signature