Fix s390 build

The goal of this patch is to make isa-l testsuite pass on s390 with
minimal changes to the library. The one and only reason isa-l does not
work on s390 at the moment is that s390 is big-endian, and isa-l
assumes little-endian at a lot of places.

There are two flavors of this: loading/storing integers from/to
memory, and overlapping structs. Loads/stores are already helpfully
wrapped by unaligned.h header, so replace the functions there with
endianness-aware variants. Solve struct member overlap by reversing
their order on big-endian.

Also, fix a couple of usages of uninitialized memory in the testsuite
(found with MemorySanitizer).

Fixes s390x part of #188.

Change-Id: Iaf14a113bd266900192cc8b44212f8a47a8c7753
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
This commit is contained in:
Ilya Leoshkevich 2021-11-11 12:53:38 +01:00 committed by Greg Tucker
parent 3b3d7cc47b
commit d3cfb2fb77
17 changed files with 313 additions and 169 deletions

View File

@ -171,7 +171,7 @@ void gf_vect_mul_init(unsigned char c, unsigned char *tbl)
unsigned char c4 = (c2 << 1) ^ ((c2 & 0x80) ? 0x1d : 0); //Mult by GF{2}
unsigned char c8 = (c4 << 1) ^ ((c4 & 0x80) ? 0x1d : 0); //Mult by GF{2}
#if __WORDSIZE == 64 || _WIN64 || __x86_64__
#if (__WORDSIZE == 64 || _WIN64 || __x86_64__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
unsigned long long v1, v2, v4, v8, *t;
unsigned long long v10, v20, v40, v80;
unsigned char c17, c18, c20, c24;

View File

@ -36,7 +36,6 @@
#define inline __inline
#endif
/* MAX_BITBUF_BIT WRITE is the maximum number of bits than can be safely written
* by consecutive calls of write_bits. Note this assumes the bitbuf is in a
* state that is possible at the exit of write_bits */
@ -60,28 +59,28 @@ static inline int is_full(struct BitBuf2 *me)
return (me->m_out_buf > me->m_out_end);
}
static inline uint8_t * buffer_ptr(struct BitBuf2 *me)
static inline uint8_t *buffer_ptr(struct BitBuf2 *me)
{
return me->m_out_buf;
}
static inline uint32_t buffer_used(struct BitBuf2 *me)
{
return (uint32_t)(me->m_out_buf - me->m_out_start);
return (uint32_t) (me->m_out_buf - me->m_out_start);
}
static inline uint32_t buffer_bits_used(struct BitBuf2 *me)
{
return (8 * (uint32_t)(me->m_out_buf - me->m_out_start) + me->m_bit_count);
return (8 * (uint32_t) (me->m_out_buf - me->m_out_start) + me->m_bit_count);
}
static inline void flush_bits(struct BitBuf2 *me)
{
uint32_t bits;
store_u64(me->m_out_buf, me->m_bits);
store_le_u64(me->m_out_buf, me->m_bits);
bits = me->m_bit_count & ~7;
me->m_bit_count -= bits;
me->m_out_buf += bits/8;
me->m_out_buf += bits / 8;
me->m_bits >>= bits;
}
@ -91,7 +90,7 @@ static inline void flush(struct BitBuf2 *me)
{
uint32_t bytes;
if (me->m_bit_count) {
store_u64(me->m_out_buf, me->m_bits);
store_le_u64(me->m_out_buf, me->m_bits);
bytes = (me->m_bit_count + 7) / 8;
me->m_out_buf += bytes;
}
@ -114,14 +113,14 @@ static inline void write_bits_unsafe(struct BitBuf2 *me, uint64_t code, uint32_t
}
static inline void write_bits(struct BitBuf2 *me, uint64_t code, uint32_t count)
{ /* Assumes there is space to fit code into m_bits. */
{ /* Assumes there is space to fit code into m_bits. */
me->m_bits |= code << me->m_bit_count;
me->m_bit_count += count;
flush_bits(me);
}
static inline void write_bits_flush(struct BitBuf2 *me, uint64_t code, uint32_t count)
{ /* Assumes there is space to fit code into m_bits. */
{ /* Assumes there is space to fit code into m_bits. */
me->m_bits |= code << me->m_bit_count;
me->m_bit_count += count;
flush(me);

View File

@ -20,11 +20,17 @@
#define ICF_CODE_LEN 32
struct deflate_icf {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t lit_len:LIT_LEN_BIT_COUNT;
uint32_t lit_dist:DIST_LIT_BIT_COUNT;
uint32_t dist_extra:ICF_CODE_LEN - DIST_LIT_BIT_COUNT - ICF_DIST_OFFSET;
#else
uint32_t dist_extra:ICF_CODE_LEN - DIST_LIT_BIT_COUNT - ICF_DIST_OFFSET;
uint32_t lit_dist:DIST_LIT_BIT_COUNT;
uint32_t lit_len:LIT_LEN_BIT_COUNT;
#endif
};
struct deflate_icf *encode_deflate_icf(struct deflate_icf *next_in, struct deflate_icf *end_in,
struct BitBuf2 *bb, struct hufftables_icf * hufftables);
struct BitBuf2 *bb, struct hufftables_icf *hufftables);
#endif

View File

@ -291,13 +291,13 @@ void isal_update_histogram_dict(uint8_t * start_stream, int dict_length, int len
memset(last_seen, 0, sizeof(histogram->hash_table)); /* Initialize last_seen to be 0. */
for (current = start_stream; current < end_dict - 4; current++) {
literal = load_u32(current);
literal = load_le_u32(current);
hash = compute_hash(literal) & LVL0_HASH_MASK;
last_seen[hash] = (current - start_stream) & 0xFFFF;
}
for (current = start_stream + dict_length; current < end_stream - 3; current++) {
literal = load_u32(current);
literal = load_le_u32(current);
hash = compute_hash(literal) & LVL0_HASH_MASK;
seen = last_seen[hash];
last_seen[hash] = (current - start_stream) & 0xFFFF;
@ -317,7 +317,7 @@ void isal_update_histogram_dict(uint8_t * start_stream, int dict_length, int len
end = end_stream - 3;
next_hash++;
for (; next_hash < end; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash(literal) & LVL0_HASH_MASK;
last_seen[hash] = (next_hash - start_stream) & 0xFFFF;
}

View File

@ -680,7 +680,7 @@ void isal_update_histogram_base(uint8_t * start_stream, int length,
end_stream = start_stream + length;
memset(last_seen, 0, sizeof(histogram->hash_table)); /* Initialize last_seen to be 0. */
for (current = start_stream; current < end_stream - 3; current++) {
literal = load_u32(current);
literal = load_le_u32(current);
hash = compute_hash(literal) & LVL0_HASH_MASK;
seen = last_seen[hash];
last_seen[hash] = (current - start_stream) & 0xFFFF;
@ -700,7 +700,7 @@ void isal_update_histogram_base(uint8_t * start_stream, int length,
end = end_stream - 3;
next_hash++;
for (; next_hash < end; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash(literal) & LVL0_HASH_MASK;
last_seen[hash] = (next_hash - start_stream) & 0xFFFF;
}

View File

@ -104,15 +104,26 @@
*/
struct huff_code {
union {
struct {
uint32_t code_and_extra:24;
uint32_t length2:8;
};
struct {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t code_and_extra:24;
uint32_t length2:8;
#else
uint32_t length2:8;
uint32_t code_and_extra:24;
#endif
};
struct {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint16_t code;
uint8_t extra_bit_count;
uint8_t length;
#else
uint8_t length;
uint8_t extra_bit_count;
uint16_t code;
#endif
};
uint32_t code_and_length;
@ -120,8 +131,13 @@ struct huff_code {
};
struct tree_node {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t child;
uint32_t depth;
#else
uint32_t depth;
uint32_t child;
#endif
};
struct heap_tree {
@ -164,7 +180,7 @@ struct hufftables_icf {
* with the set hufftable
*/
uint64_t
create_hufftables_icf(struct BitBuf2 *bb, struct hufftables_icf * hufftables,
struct isal_mod_hist *hist, uint32_t end_of_block);
create_hufftables_icf(struct BitBuf2 *bb, struct hufftables_icf *hufftables,
struct isal_mod_hist *hist, uint32_t end_of_block);
#endif

View File

@ -58,15 +58,14 @@ static inline uint32_t bsr(uint32_t val)
if (val != 0) {
_BitScanReverse(&ret, val);
msb = ret + 1;
}
else
} else
msb = 0;
#elif defined( __LZCNT__)
msb = 32 - __lzcnt32(val);
#elif defined(__x86_64__) || defined(__aarch64__)
msb = (val == 0)? 0 : 32 - __builtin_clz(val);
msb = (val == 0) ? 0 : 32 - __builtin_clz(val);
#else
for(msb = 0; val > 0; val >>= 1)
for (msb = 0; val > 0; val >>= 1)
msb++;
#endif
return msb;
@ -81,17 +80,18 @@ static inline uint32_t tzbytecnt(uint64_t val)
cnt = cnt / 8;
#elif defined(__x86_64__) || defined(__aarch64__)
cnt = (val == 0)? 64 : __builtin_ctzll(val);
cnt = (val == 0) ? 64 : __builtin_ctzll(val);
cnt = cnt / 8;
#else
for(cnt = 8; val > 0; val <<= 8)
for (cnt = 8; val > 0; val <<= 8)
cnt -= 1;
#endif
return cnt;
}
static void compute_dist_code(struct isal_hufftables *hufftables, uint16_t dist, uint64_t *p_code, uint64_t *p_len)
static void compute_dist_code(struct isal_hufftables *hufftables, uint16_t dist,
uint64_t * p_code, uint64_t * p_len)
{
assert(dist > IGZIP_DIST_TABLE_SIZE);
@ -116,7 +116,8 @@ static void compute_dist_code(struct isal_hufftables *hufftables, uint16_t dist,
*p_len = len + num_extra_bits;
}
static inline void get_dist_code(struct isal_hufftables *hufftables, uint32_t dist, uint64_t *code, uint64_t *len)
static inline void get_dist_code(struct isal_hufftables *hufftables, uint32_t dist,
uint64_t * code, uint64_t * len)
{
if (dist < 1)
dist = 0;
@ -132,7 +133,8 @@ static inline void get_dist_code(struct isal_hufftables *hufftables, uint32_t di
}
}
static inline void get_len_code(struct isal_hufftables *hufftables, uint32_t length, uint64_t *code, uint64_t *len)
static inline void get_len_code(struct isal_hufftables *hufftables, uint32_t length,
uint64_t * code, uint64_t * len)
{
assert(length >= 3);
assert(length <= 258);
@ -143,7 +145,8 @@ static inline void get_len_code(struct isal_hufftables *hufftables, uint32_t len
*len = code_len & 0x1F;
}
static inline void get_lit_code(struct isal_hufftables *hufftables, uint32_t lit, uint64_t *code, uint64_t *len)
static inline void get_lit_code(struct isal_hufftables *hufftables, uint32_t lit,
uint64_t * code, uint64_t * len)
{
assert(lit <= 256);
@ -151,7 +154,7 @@ static inline void get_lit_code(struct isal_hufftables *hufftables, uint32_t lit
*len = hufftables->lit_table_sizes[lit];
}
static void compute_dist_icf_code(uint32_t dist, uint32_t *code, uint32_t *extra_bits)
static void compute_dist_icf_code(uint32_t dist, uint32_t * code, uint32_t * extra_bits)
{
uint32_t msb;
uint32_t num_extra_bits;
@ -166,7 +169,7 @@ static void compute_dist_icf_code(uint32_t dist, uint32_t *code, uint32_t *extra
assert(*code < 30);
}
static inline void get_dist_icf_code(uint32_t dist, uint32_t *code, uint32_t *extra_bits)
static inline void get_dist_icf_code(uint32_t dist, uint32_t * code, uint32_t * extra_bits)
{
assert(dist >= 1);
assert(dist <= 32768);
@ -178,7 +181,7 @@ static inline void get_dist_icf_code(uint32_t dist, uint32_t *code, uint32_t *ex
}
}
static inline void get_len_icf_code(uint32_t length, uint32_t *code)
static inline void get_len_icf_code(uint32_t length, uint32_t * code)
{
assert(length >= 3);
assert(length <= 258);
@ -186,7 +189,7 @@ static inline void get_len_icf_code(uint32_t length, uint32_t *code)
*code = length + 254;
}
static inline void get_lit_icf_code(uint32_t lit, uint32_t *code)
static inline void get_lit_icf_code(uint32_t lit, uint32_t * code)
{
assert(lit <= 256);
@ -234,9 +237,10 @@ static inline uint32_t compute_hash_mad(uint32_t data)
return data;
}
static inline uint32_t compute_long_hash(uint64_t data) {
static inline uint32_t compute_long_hash(uint64_t data)
{
return compute_hash(data >> 32)^compute_hash(data);
return compute_hash(data >> 32) ^ compute_hash(data);
}
/**
@ -251,48 +255,48 @@ static inline int compare258(uint8_t * str1, uint8_t * str2, uint32_t max_length
uint64_t test;
uint64_t loop_length;
if(max_length > 258)
if (max_length > 258)
max_length = 258;
loop_length = max_length & ~0x7;
for(count = 0; count < loop_length; count += 8){
test = load_u64(str1);
test ^= load_u64(str2);
if(test != 0)
for (count = 0; count < loop_length; count += 8) {
test = load_le_u64(str1);
test ^= load_le_u64(str2);
if (test != 0)
return count + tzbytecnt(test);
str1 += 8;
str2 += 8;
}
switch(max_length % 8){
switch (max_length % 8) {
case 7:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 6:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 5:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 4:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 3:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 2:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 1:
if(*str1 != *str2)
if (*str1 != *str2)
return count;
count++;
}
@ -314,43 +318,43 @@ static inline int compare(uint8_t * str1, uint8_t * str2, uint32_t max_length)
loop_length = max_length & ~0x7;
for(count = 0; count < loop_length; count += 8){
test = load_u64(str1);
test ^= load_u64(str2);
if(test != 0)
for (count = 0; count < loop_length; count += 8) {
test = load_le_u64(str1);
test ^= load_le_u64(str2);
if (test != 0)
return count + tzbytecnt(test);
str1 += 8;
str2 += 8;
}
switch(max_length % 8){
switch (max_length % 8) {
case 7:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 6:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 5:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 4:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 3:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 2:
if(*str1++ != *str2++)
if (*str1++ != *str2++)
return count;
count++;
case 1:
if(*str1 != *str2)
if (*str1 != *str2)
return count;
count++;
}

View File

@ -54,20 +54,6 @@
#include "igzip_wrapper.h"
#include "unaligned.h"
#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/endian.h>
# define to_be32(x) bswap32(x)
#elif defined (__APPLE__)
#include <libkern/OSByteOrder.h>
# define to_be32(x) OSSwapInt32(x)
#elif defined (__GNUC__) && !defined (__MINGW32__)
# include <byteswap.h>
# define to_be32(x) bswap_32(x)
#elif defined _WIN64
# define to_be32(x) _byteswap_ulong(x)
#endif
extern void isal_deflate_hash_lvl0(uint16_t *, uint32_t, uint32_t, uint8_t *, uint32_t);
extern void isal_deflate_hash_lvl1(uint16_t *, uint32_t, uint32_t, uint8_t *, uint32_t);
extern void isal_deflate_hash_lvl2(uint16_t *, uint32_t, uint32_t, uint8_t *, uint32_t);
@ -744,8 +730,8 @@ static int isal_deflate_int_stateless(struct isal_zstream *stream)
return STATELESS_OVERFLOW;
if (stream->avail_in >= 8
&& (load_u64(stream->next_in) == 0
|| load_u64(stream->next_in) == ~(uint64_t) 0)) {
&& (load_native_u64(stream->next_in) == 0
|| load_native_u64(stream->next_in) == ~(uint64_t) 0)) {
repeat_length = detect_repeated_char_length(stream->next_in, stream->avail_in);
if (stream->avail_in == repeat_length || repeat_length >= MIN_REPEAT_LEN)
@ -809,6 +795,7 @@ static void write_type0_header(struct isal_zstream *stream)
stored_blk_hdr = stored_blk_hdr << 8;
stored_blk_hdr |= stream->internal_state.has_eob_hdr;
memcpy_len = TYPE0_HDR_LEN + 1;
stored_blk_hdr = to_le64(stored_blk_hdr);
memcpy(stream->next_out, &stored_blk_hdr, memcpy_len);
} else if (stream->avail_out >= 8) {
set_buf(bitbuf, stream->next_out, stream->avail_out);
@ -817,6 +804,7 @@ static void write_type0_header(struct isal_zstream *stream)
stream->total_out += buffer_used(bitbuf);
stream->avail_out -= buffer_used(bitbuf);
memcpy_len = TYPE0_HDR_LEN;
stored_blk_hdr = to_le64(stored_blk_hdr);
memcpy(stream->next_out, &stored_blk_hdr, memcpy_len);
} else {
stream->internal_state.has_eob_hdr = 0;
@ -1100,13 +1088,13 @@ uint32_t isal_write_gzip_header(struct isal_zstream *stream, struct isal_gzip_he
out_buf[1] = 0x8b;
out_buf[2] = DEFLATE_METHOD;
out_buf[3] = flags;
store_u32(out_buf + 4, gz_hdr->time);
store_le_u32(out_buf + 4, gz_hdr->time);
out_buf[8] = gz_hdr->xflags;
out_buf[9] = gz_hdr->os;
out_buf += GZIP_HDR_BASE;
if (flags & EXTRA_FLAG) {
store_u16(out_buf, gz_hdr->extra_len);
store_le_u16(out_buf, gz_hdr->extra_len);
out_buf += GZIP_EXTRA_LEN;
memcpy(out_buf, gz_hdr->extra, gz_hdr->extra_len);
@ -1125,7 +1113,7 @@ uint32_t isal_write_gzip_header(struct isal_zstream *stream, struct isal_gzip_he
if (flags & HCRC_FLAG) {
hcrc = crc32_gzip_refl(0, out_buf_start, out_buf - out_buf_start);
store_u16(out_buf, hcrc);
store_le_u16(out_buf, hcrc);
out_buf += GZIP_HCRC_LEN;
}
@ -1158,7 +1146,7 @@ uint32_t isal_write_zlib_header(struct isal_zstream *stream, struct isal_zlib_he
out_buf[1] = flg;
if (dict_flag)
store_u32(out_buf + 2, z_hdr->dict_id);
store_le_u32(out_buf + 2, z_hdr->dict_id);
stream->next_out += hdr_size;
stream->total_out += hdr_size;
@ -1877,7 +1865,7 @@ static int write_deflate_header_unaligned_stateless(struct isal_zstream *stream)
header_end = header_next +
(hufftables->deflate_hdr_count / sizeof(header_bits)) * sizeof(header_bits);
header_bits = load_u64(header_next);
header_bits = load_le_u64(header_next);
if (stream->end_of_stream == 0)
header_bits--;
@ -1891,7 +1879,7 @@ static int write_deflate_header_unaligned_stateless(struct isal_zstream *stream)
write_bits(&state->bitbuf, header_bits, 32);
header_bits >>= 32;
write_bits(&state->bitbuf, header_bits, 32);
header_bits = load_u64(header_next);
header_bits = load_le_u64(header_next);
}
bit_count =
(hufftables->deflate_hdr_count & 0x7) * 8 + hufftables->deflate_hdr_extra_bits;
@ -2032,7 +2020,8 @@ static void write_trailer(struct isal_zstream *stream)
case IGZIP_GZIP:
case IGZIP_GZIP_NO_HDR:
if (stream->avail_out - bytes >= gzip_trl_bytes) {
store_u64(stream->next_out, ((uint64_t) stream->total_in << 32) | crc);
store_le_u64(stream->next_out,
((uint64_t) stream->total_in << 32) | crc);
stream->next_out += gzip_trl_bytes;
bytes += gzip_trl_bytes;
state->state = ZSTATE_END;
@ -2042,9 +2031,8 @@ static void write_trailer(struct isal_zstream *stream)
case IGZIP_ZLIB:
case IGZIP_ZLIB_NO_HDR:
if (stream->avail_out - bytes >= zlib_trl_bytes) {
store_u32(stream->next_out,
to_be32((crc & 0xFFFF0000) | ((crc & 0xFFFF) + 1) %
ADLER_MOD));
store_be_u32(stream->next_out,
(crc & 0xFFFF0000) | ((crc & 0xFFFF) + 1) % ADLER_MOD);
stream->next_out += zlib_trl_bytes;
bytes += zlib_trl_bytes;
state->state = ZSTATE_END;

View File

@ -58,7 +58,7 @@ void isal_deflate_body_base(struct isal_zstream *stream)
return;
}
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash(literal) & hash_mask;
dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
last_seen[hash] = (uint64_t) (next_in - file_start);
@ -79,7 +79,7 @@ void isal_deflate_body_base(struct isal_zstream *stream)
next_hash++;
for (; next_hash < end; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash(literal) & hash_mask;
last_seen[hash] = (uint64_t) (next_hash - file_start);
}
@ -140,7 +140,7 @@ void isal_deflate_finish_base(struct isal_zstream *stream)
return;
}
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash(literal) & hash_mask;
dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
last_seen[hash] = (uint64_t) (next_in - file_start);
@ -159,7 +159,7 @@ void isal_deflate_finish_base(struct isal_zstream *stream)
next_hash++;
for (; next_hash < end - 3; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash(literal) & hash_mask;
last_seen[hash] =
(uint64_t) (next_hash - file_start);
@ -227,7 +227,7 @@ void isal_deflate_hash_base(uint16_t * hash_table, uint32_t hash_mask,
uint16_t index = current_index - dict_len;
while (next_in <= end_in) {
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash(literal) & hash_mask;
hash_table[hash] = index;
index++;

View File

@ -73,7 +73,7 @@ void isal_deflate_icf_body_hash_hist_base(struct isal_zstream *stream)
return;
}
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash(literal) & hash_mask;
dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
last_seen[hash] = (uint64_t) (next_in - file_start);
@ -94,7 +94,7 @@ void isal_deflate_icf_body_hash_hist_base(struct isal_zstream *stream)
next_hash++;
for (; next_hash < end; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash(literal) & hash_mask;
last_seen[hash] = (uint64_t) (next_hash - file_start);
}
@ -168,7 +168,7 @@ void isal_deflate_icf_finish_hash_hist_base(struct isal_zstream *stream)
return;
}
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash(literal) & hash_mask;
dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
last_seen[hash] = (uint64_t) (next_in - file_start);
@ -186,7 +186,7 @@ void isal_deflate_icf_finish_hash_hist_base(struct isal_zstream *stream)
next_hash++;
for (; next_hash < end - 3; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash(literal) & hash_mask;
last_seen[hash] = (uint64_t) (next_hash - file_start);
}
@ -278,7 +278,7 @@ void isal_deflate_icf_finish_hash_map_base(struct isal_zstream *stream)
return;
}
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash_mad(literal) & hash_mask;
dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
last_seen[hash] = (uint64_t) (next_in - file_start);
@ -296,7 +296,7 @@ void isal_deflate_icf_finish_hash_map_base(struct isal_zstream *stream)
next_hash++;
for (; next_hash < end - 3; next_hash++) {
literal = load_u32(next_hash);
literal = load_le_u32(next_hash);
hash = compute_hash_mad(literal) & hash_mask;
last_seen[hash] = (uint64_t) (next_hash - file_start);
}
@ -361,7 +361,7 @@ void isal_deflate_hash_mad_base(uint16_t * hash_table, uint32_t hash_mask,
uint16_t index = current_index - dict_len;
while (next_in <= end_in) {
literal = load_u32(next_in);
literal = load_le_u32(next_in);
hash = compute_hash_mad(literal) & hash_mask;
hash_table[hash] = index;
index++;

View File

@ -20,8 +20,8 @@ static inline void write_deflate_icf(struct deflate_icf *icf, uint32_t lit_len,
/* icf->lit_dist = lit_dist; */
/* icf->dist_extra = extra_bits; */
store_u32((uint8_t *) icf, lit_len | (lit_dist << LIT_LEN_BIT_COUNT)
| (extra_bits << (LIT_LEN_BIT_COUNT + DIST_LIT_BIT_COUNT)));
store_native_u32((uint8_t *) icf, lit_len | (lit_dist << LIT_LEN_BIT_COUNT)
| (extra_bits << (LIT_LEN_BIT_COUNT + DIST_LIT_BIT_COUNT)));
}
void set_long_icf_fg_base(uint8_t * next_in, uint64_t processed, uint64_t input_size,
@ -94,7 +94,7 @@ uint64_t gen_icf_map_h1_base(struct isal_zstream *stream,
matches_icf_lookup->lit_dist = 0x1e;
matches_icf_lookup->dist_extra = 0;
hash = compute_hash(load_u32(next_in)) & hash_mask;
hash = compute_hash(load_le_u32(next_in)) & hash_mask;
hash_table[hash] = (uint64_t) (next_in - file_start);
next_in++;
@ -103,13 +103,13 @@ uint64_t gen_icf_map_h1_base(struct isal_zstream *stream,
}
while (next_in < end_in - ISAL_LOOK_AHEAD) {
hash = compute_hash(load_u32(next_in)) & hash_mask;
hash = compute_hash(load_le_u32(next_in)) & hash_mask;
dist = (next_in - file_start - hash_table[hash]);
dist = ((dist - 1) & hist_size) + 1;
hash_table[hash] = (uint64_t) (next_in - file_start);
match_bytes = load_u64(next_in - dist);
next_bytes = load_u64(next_in);
match_bytes = load_le_u64(next_in - dist);
next_bytes = load_le_u64(next_in);
match = next_bytes ^ match_bytes;
len = tzbytecnt(match);
@ -147,13 +147,18 @@ static struct deflate_icf *compress_icf_map_g(struct isal_zstream *stream,
level_buf->icf_buf_avail_out / sizeof(struct deflate_icf);
while (matches_next < matches_end - 1 && level_buf->icf_buf_next < icf_buf_end - 1) {
code = load_u64((uint8_t *) matches_next);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
code = load_native_u64((uint8_t *) matches_next);
#else
code = load_native_u32((uint8_t *) matches_next) |
((uint64_t) load_native_u32((uint8_t *) (matches_next + 1)) << 32);
#endif
lit_len = code & LIT_LEN_MASK;
lit_len2 = (code >> ICF_CODE_LEN) & LIT_LEN_MASK;
level_buf->hist.ll_hist[lit_len]++;
if (lit_len >= LEN_START) {
store_u32((uint8_t *) level_buf->icf_buf_next, code);
store_native_u32((uint8_t *) level_buf->icf_buf_next, code);
level_buf->icf_buf_next++;
dist = (code >> ICF_DIST_OFFSET) & DIST_LIT_MASK;
@ -162,7 +167,13 @@ static struct deflate_icf *compress_icf_map_g(struct isal_zstream *stream,
matches_next += lit_len;
} else if (lit_len2 >= LEN_START) {
store_u64((uint8_t *) level_buf->icf_buf_next, code);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
store_native_u64((uint8_t *) level_buf->icf_buf_next, code);
#else
store_native_u32((uint8_t *) level_buf->icf_buf_next, (uint32_t) code);
store_native_u32((uint8_t *) (level_buf->icf_buf_next + 1),
(uint32_t) (code >> 32));
#endif
level_buf->icf_buf_next += 2;
level_buf->hist.ll_hist[lit_len2]++;
@ -174,7 +185,7 @@ static struct deflate_icf *compress_icf_map_g(struct isal_zstream *stream,
} else {
code = ((lit_len2 + LIT_START) << ICF_DIST_OFFSET) | lit_len;
store_u32((uint8_t *) level_buf->icf_buf_next, code);
store_native_u32((uint8_t *) level_buf->icf_buf_next, code);
level_buf->icf_buf_next++;
level_buf->hist.ll_hist[lit_len2]++;
@ -184,9 +195,9 @@ static struct deflate_icf *compress_icf_map_g(struct isal_zstream *stream,
}
while (matches_next < matches_end && level_buf->icf_buf_next < icf_buf_end) {
code = load_u32((uint8_t *) matches_next);
code = load_native_u32((uint8_t *) matches_next);
lit_len = code & LIT_LEN_MASK;
store_u32((uint8_t *) level_buf->icf_buf_next, code);
store_native_u32((uint8_t *) level_buf->icf_buf_next, code);
level_buf->icf_buf_next++;
level_buf->hist.ll_hist[lit_len]++;

View File

@ -39,19 +39,6 @@
#include "static_inflate.h"
#endif
#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/endian.h>
# define bswap_32(x) bswap32(x)
#elif defined (__APPLE__)
#include <libkern/OSByteOrder.h>
# define bswap_32(x) OSSwapInt32(x)
#elif defined (__GNUC__) && !defined (__MINGW32__)
# include <byteswap.h>
#elif defined _WIN64
# define bswap_32(x) _byteswap_ulong(x)
#endif
extern int decode_huffman_code_block_stateless(struct inflate_state *, uint8_t * start_out);
extern struct isal_hufftables hufftables_default; /* For known header detection */
@ -255,7 +242,7 @@ static void inline inflate_in_load(struct inflate_state *state, int min_required
/* If there is enough space to load a 64 bits, load the data and use
* that to fill read_in */
new_bytes = 8 - (state->read_in_length + 7) / 8;
temp = load_u64(state->next_in);
temp = load_le_u64(state->next_in);
state->read_in |= temp << state->read_in_length;
state->next_in += new_bytes;
@ -948,7 +935,7 @@ static int header_matches_pregen(struct inflate_state *state)
/* Check if stashed read_in_bytes match header */
hdr = &(hufftables_default.deflate_hdr[0]);
bits_read_mask = (1ull << state->read_in_length) - 1;
hdr_stash = (load_u64(hdr) >> bits_read_prior) & bits_read_mask;
hdr_stash = (load_le_u64(hdr) >> bits_read_prior) & bits_read_mask;
in_stash = state->read_in & bits_read_mask;
if (hdr_stash != in_stash)
@ -1200,7 +1187,7 @@ static uint16_t inline decode_next_header(struct inflate_state *state,
/* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0,
* next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10
* represent the length of that symbols huffman code. If next_sym is not
* a symbol, it provides a hint of where the large symbols containin
* a symbol, it provides a hint of where the large symbols containing
* this code are located. Note the hint is at largest the location the
* first actual symbol in the long code list.*/
next_sym = huff_code->short_code_lookup[next_bits];
@ -1574,6 +1561,7 @@ static int inline decode_literal_block(struct inflate_state *state)
{
uint32_t len = state->type0_block_len;
uint32_t bytes = state->read_in_length / 8;
uint64_t read_in;
/* If the block is uncompressed, perform a memcopy while
* updating state data */
state->block_state = state->bfinal ? ISAL_BLOCK_INPUT_DONE : ISAL_BLOCK_NEW_HDR;
@ -1588,8 +1576,9 @@ static int inline decode_literal_block(struct inflate_state *state)
state->block_state = ISAL_BLOCK_TYPE0;
}
if (state->read_in_length) {
read_in = to_le64(state->read_in);
if (len >= bytes) {
memcpy(state->next_out, &state->read_in, bytes);
memcpy(state->next_out, &read_in, bytes);
state->next_out += bytes;
state->avail_out -= bytes;
@ -1602,7 +1591,7 @@ static int inline decode_literal_block(struct inflate_state *state)
bytes = 0;
} else {
memcpy(state->next_out, &state->read_in, len);
memcpy(state->next_out, &read_in, len);
state->next_out += len;
state->avail_out -= len;
@ -1946,8 +1935,8 @@ static int check_gzip_checksum(struct inflate_state *state)
byte_count = state->read_in_length / 8;
offset = state->read_in_length % 8;
store_u64(state->tmp_in_buffer + tmp_in_size,
state->read_in >> offset);
store_le_u64(state->tmp_in_buffer + tmp_in_size,
state->read_in >> offset);
state->read_in = 0;
state->read_in_length = 0;
@ -1961,7 +1950,7 @@ static int check_gzip_checksum(struct inflate_state *state)
return ret;
}
trailer = load_u64(next_in);
trailer = load_le_u64(next_in);
}
state->block_state = ISAL_BLOCK_FINISH;
@ -1997,8 +1986,8 @@ static int check_zlib_checksum(struct inflate_state *state)
byte_count = state->read_in_length / 8;
offset = state->read_in_length % 8;
store_u64(state->tmp_in_buffer + tmp_in_size,
state->read_in >> offset);
store_le_u64(state->tmp_in_buffer + tmp_in_size,
state->read_in >> offset);
state->read_in = 0;
state->read_in_length = 0;
@ -2012,12 +2001,12 @@ static int check_zlib_checksum(struct inflate_state *state)
return ret;
}
trailer = load_u32(next_in);
trailer = load_le_u32(next_in);
}
state->block_state = ISAL_BLOCK_FINISH;
if (bswap_32(trailer) != state->crc)
if (isal_bswap32(trailer) != state->crc)
return ISAL_INCORRECT_CHECKSUM;
else
return ISAL_DECOMP_OK;
@ -2051,7 +2040,7 @@ int isal_read_gzip_header(struct inflate_state *state, struct isal_gzip_header *
id2 = next_in[1];
cm = next_in[2];
flags = next_in[3];
gz_hdr->time = load_u32(next_in + 4);
gz_hdr->time = load_le_u32(next_in + 4);
gz_hdr->xflags = *(next_in + 8);
gz_hdr->os = *(next_in + 9);
@ -2075,7 +2064,7 @@ int isal_read_gzip_header(struct inflate_state *state, struct isal_gzip_header *
break;
}
xlen = load_u16(next_in);
xlen = load_le_u16(next_in);
count = xlen;
gz_hdr->extra_len = xlen;
@ -2130,7 +2119,7 @@ int isal_read_gzip_header(struct inflate_state *state, struct isal_gzip_header *
return ret;
}
if ((hcrc & 0xffff) != load_u16(next_in))
if ((hcrc & 0xffff) != load_le_u16(next_in))
return ISAL_INCORRECT_CHECKSUM;
}
@ -2181,7 +2170,7 @@ int isal_read_zlib_header(struct inflate_state *state, struct isal_zlib_header *
break;
}
zlib_hdr->dict_id = load_u32(next_in);
zlib_hdr->dict_id = load_le_u32(next_in);
}
state->wrapper_flag = 1;
@ -2370,7 +2359,7 @@ int isal_inflate(struct inflate_state *state)
/* Copy valid data from internal buffer into out_buffer */
if (state->write_overflow_len != 0) {
store_u32(state->next_out, state->write_overflow_lits);
store_le_u32(state->next_out, state->write_overflow_lits);
state->next_out += state->write_overflow_len;
state->total_out += state->write_overflow_len;
state->write_overflow_lits = 0;
@ -2468,8 +2457,8 @@ int isal_inflate(struct inflate_state *state)
/* Write overflow data into tmp buffer */
if (state->write_overflow_len != 0) {
store_u32(&state->tmp_out_buffer[state->tmp_out_valid],
state->write_overflow_lits);
store_le_u32(&state->tmp_out_buffer[state->tmp_out_valid],
state->write_overflow_lits);
state->tmp_out_valid += state->write_overflow_len;
state->total_out += state->write_overflow_len;
state->write_overflow_lits = 0;

View File

@ -546,7 +546,7 @@ int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
if (!ret)
ret =
check_gzip_trl(load_u64(state.next_in - offset),
check_gzip_trl(load_le_u64(state.next_in - offset),
state.crc, uncompress_buf, *uncompress_len);
else if (ret == ISAL_INCORRECT_CHECKSUM)
ret = INCORRECT_GZIP_TRAILER;
@ -558,7 +558,7 @@ int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
if (!ret)
ret =
check_zlib_trl(load_u32(state.next_in - offset),
check_zlib_trl(load_le_u32(state.next_in - offset),
state.crc, uncompress_buf, *uncompress_len);
else if (ret == ISAL_INCORRECT_CHECKSUM)
ret = INCORRECT_ZLIB_TRAILER;
@ -743,6 +743,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
printf("Failed to allocate memory\n");
return MALLOC_FAILED;
}
memset(uncomp_tmp, 0, uncomp_tmp_size);
state->avail_out = uncomp_tmp_size;
state->next_out = uncomp_tmp;
@ -802,7 +803,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
|| gzip_flag == IGZIP_GZIP)
compress_len -= gzip_trl_bytes;
ret =
check_gzip_trl(load_u64(compress_buf + compress_len),
check_gzip_trl(load_le_u64(compress_buf + compress_len),
state->crc, uncompress_buf,
*uncompress_len);
} else if (gzip_flag == IGZIP_ZLIB_NO_HDR) {
@ -810,7 +811,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
|| gzip_flag == ISAL_ZLIB_NO_HDR_VER)
compress_len -= zlib_trl_bytes;
ret =
check_zlib_trl(load_u32(compress_buf + compress_len),
check_zlib_trl(load_le_u32(compress_buf + compress_len),
state->crc, uncompress_buf,
*uncompress_len);
}
@ -1152,6 +1153,7 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed
if (rand() % 2 == 0)
isal_deflate_set_dict(stream, dict, dict_len);
else {
memset(&dict_str, 0, sizeof(dict_str));
isal_deflate_process_dict(stream, &dict_str, dict, dict_len);
isal_deflate_reset_dict(stream, &dict_str);
}
@ -1347,6 +1349,7 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse
if (rand() % 2 == 0)
isal_deflate_set_dict(&stream, dict, dict_len);
else {
memset(&dict_str, 0, sizeof(dict_str));
isal_deflate_process_dict(&stream, &dict_str, dict, dict_len);
isal_deflate_reset_dict(&stream, &dict_str);
}

View File

@ -74,12 +74,12 @@ uint32_t build_huff_tree(struct heap_tree *heap_space, uint64_t heap_size, uint6
heapify(heap, heap_size, 1);
store_u16((uint8_t *) & heap[node_ptr], h1);
store_u16((uint8_t *) & heap[node_ptr - 1], h2);
store_native_u16_to_u64(&heap[node_ptr], h1);
store_native_u16_to_u64(&heap[node_ptr - 1], h2);
node_ptr -= 2;
}
h1 = heap[1];
store_u16((uint8_t *) & heap[node_ptr], h1);
store_native_u16_to_u64(&heap[node_ptr], h1);
return node_ptr;
}

View File

@ -31,46 +31,174 @@
#define UNALIGNED_H
#include "stdint.h"
#include "stdlib.h"
#include "string.h"
static inline uint16_t load_u16(uint8_t * buf) {
#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/endian.h>
# define isal_bswap16(x) bswap16(x)
# define isal_bswap32(x) bswap32(x)
# define isal_bswap64(x) bswap64(x)
#elif defined (__APPLE__)
#include <libkern/OSByteOrder.h>
# define isal_bswap16(x) OSSwapInt16(x)
# define isal_bswap32(x) OSSwapInt32(x)
# define isal_bswap64(x) OSSwapInt64(x)
#elif defined (__GNUC__) && !defined (__MINGW32__)
# include <byteswap.h>
# define isal_bswap16(x) bswap_16(x)
# define isal_bswap32(x) bswap_32(x)
# define isal_bswap64(x) bswap_64(x)
#elif defined _WIN64
# define isal_bswap16(x) _byteswap_ushort(x)
# define isal_bswap32(x) _byteswap_ulong(x)
# define isal_bswap64(x) _byteswap_uint64(x)
#endif
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define to_be16(x) isal_bswap16(x)
# define from_be16(x) isal_bswap16(x)
# define to_be32(x) isal_bswap32(x)
# define from_be32(x) isal_bswap32(x)
# define to_be64(x) isal_bswap64(x)
# define from_be64(x) isal_bswap64(x)
# define to_le16(x) (x)
# define from_le16(x) (x)
# define to_le32(x) (x)
# define from_le32(x) (x)
# define to_le64(x) (x)
# define from_le64(x) (x)
#else
# define to_be16(x) (x)
# define from_be16(x) (x)
# define to_be32(x) (x)
# define from_be32(x) (x)
# define to_be64(x) (x)
# define from_be64(x) (x)
# define to_le16(x) isal_bswap16(x)
# define from_le16(x) isal_bswap16(x)
# define to_le32(x) isal_bswap32(x)
# define from_le32(x) isal_bswap32(x)
# define to_le64(x) isal_bswap64(x)
# define from_le64(x) isal_bswap64(x)
#endif
static inline uint16_t load_native_u16(uint8_t * buf)
{
uint16_t ret;
memcpy(&ret, buf, sizeof(ret));
return ret;
}
static inline uint32_t load_u32(uint8_t * buf) {
static inline uint16_t load_le_u16(uint8_t * buf)
{
return from_le16(load_native_u16(buf));
}
static inline uint16_t load_be_u16(uint8_t * buf)
{
return from_be16(load_native_u16(buf));
}
static inline uint32_t load_native_u32(uint8_t * buf)
{
uint32_t ret;
memcpy(&ret, buf, sizeof(ret));
return ret;
}
static inline uint64_t load_u64(uint8_t * buf) {
static inline uint32_t load_le_u32(uint8_t * buf)
{
return from_le32(load_native_u32(buf));
}
static inline uint32_t load_be_u32(uint8_t * buf)
{
return from_be32(load_native_u32(buf));
}
static inline uint64_t load_native_u64(uint8_t * buf)
{
uint64_t ret;
memcpy(&ret, buf, sizeof(ret));
return ret;
}
static inline uintmax_t load_umax(uint8_t * buf) {
uintmax_t ret;
memcpy(&ret, buf, sizeof(ret));
return ret;
static inline uint64_t load_le_u64(uint8_t * buf)
{
return from_le64(load_native_u64(buf));
}
static inline void store_u16(uint8_t * buf, uint16_t val) {
static inline uint64_t load_be_u64(uint8_t * buf)
{
return from_be64(load_native_u64(buf));
}
static inline uintmax_t load_le_umax(uint8_t * buf)
{
switch (sizeof(uintmax_t)) {
case sizeof(uint32_t):
return from_le32(load_native_u32(buf));
case sizeof(uint64_t):
return from_le64(load_native_u64(buf));
default:
return 0;
}
}
static inline void store_native_u16(uint8_t * buf, uint16_t val)
{
memcpy(buf, &val, sizeof(val));
}
static inline void store_u32(uint8_t * buf, uint32_t val) {
static inline void store_le_u16(uint8_t * buf, uint16_t val)
{
store_native_u16(buf, to_le16(val));
}
static inline void store_be_u16(uint8_t * buf, uint16_t val)
{
store_native_u16(buf, to_be16(val));
}
static inline void store_native_u16_to_u64(uint64_t * buf, uint16_t val)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
store_native_u16((uint8_t *) buf, val);
#else
store_native_u16((uint8_t *) buf + 6, val);
#endif
}
static inline void store_native_u32(uint8_t * buf, uint32_t val)
{
memcpy(buf, &val, sizeof(val));
}
static inline void store_u64(uint8_t * buf, uint64_t val) {
static inline void store_le_u32(uint8_t * buf, uint32_t val)
{
store_native_u32(buf, to_le32(val));
}
static inline void store_be_u32(uint8_t * buf, uint32_t val)
{
store_native_u32(buf, to_be32(val));
}
static inline void store_native_u64(uint8_t * buf, uint64_t val)
{
memcpy(buf, &val, sizeof(val));
}
static inline void store_umax(uint8_t * buf, uintmax_t val) {
memcpy(buf, &val, sizeof(val));
static inline void store_le_u64(uint8_t * buf, uint64_t val)
{
store_native_u64(buf, to_le64(val));
}
static inline void store_be_u64(uint8_t * buf, uint64_t val)
{
store_native_u64(buf, to_be64(val));
}
#endif

View File

@ -39,7 +39,7 @@ int mem_zero_detect_base(void *buf, size_t n)
// Check buffer in native machine width comparisons
while (n >= sizeof(uintmax_t)) {
n -= sizeof(uintmax_t);
if (load_umax(c) != 0)
if (load_le_umax(c) != 0)
return -1;
c += sizeof(uintmax_t);
}
@ -53,12 +53,12 @@ int mem_zero_detect_base(void *buf, size_t n)
case 5:
a |= *c++; // fall through to case 4
case 4:
a |= load_u32(c);
a |= load_le_u32(c);
break;
case 3:
a |= *c++; // fall through to case 2
case 2:
a |= load_u16(c);
a |= load_le_u16(c);
break;
case 1:
a |= *c;

View File

@ -118,9 +118,9 @@ int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
int trailer_idx = cstate.total_out - trailer_size[wrapper_type];
if (wrapper_type == IGZIP_GZIP || wrapper_type == IGZIP_GZIP_NO_HDR)
crc = load_u32(&isal_cmp_buf[trailer_idx]);
crc = load_le_u32(&isal_cmp_buf[trailer_idx]);
else if (wrapper_type == IGZIP_ZLIB || wrapper_type == IGZIP_ZLIB_NO_HDR)
crc = bswap_32(load_u32(&isal_cmp_buf[trailer_idx]));
crc = load_be_u32(&isal_cmp_buf[trailer_idx]);
assert(istate.crc == crc);
free(isal_cmp_buf);