diff options
author | Yann Collet <cyan@fb.com> | 2020-11-06 22:46:48 (GMT) |
---|---|---|
committer | Yann Collet <cyan@fb.com> | 2020-11-06 22:46:48 (GMT) |
commit | e968a241293fe86c0f8b115a1223d9d78a0eda00 (patch) | |
tree | 802ce48690f51cabe19f9b35aa7c9c1240a6f3f6 /lib | |
parent | ad552101ddeef3bf1967048ecb3cc5844a1ad470 (diff) | |
download | lz4-e968a241293fe86c0f8b115a1223d9d78a0eda00.zip lz4-e968a241293fe86c0f8b115a1223d9d78a0eda00.tar.gz lz4-e968a241293fe86c0f8b115a1223d9d78a0eda00.tar.bz2 |
unified alignment test
across lz4.c and lz4hc.c
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lz4.c | 33 | ||||
-rw-r--r-- | lib/lz4hc.c | 24 |
2 files changed, 30 insertions, 27 deletions
@@ -178,6 +178,20 @@ #define unlikely(expr) expect((expr) != 0, 0) #endif +/* for some reason, Visual Studio can fail the aligment test on 32-bit x86 : + * it sometimes report an aligment of 8-bytes (at least in some configurations), + * while only providing a `malloc()` memory area aligned on 4-bytes, + * which is inconsistent with malloc() contract. + * The source of the issue is still unclear. + * Mitigation : made the alignment test optional */ +#ifndef LZ4_ALIGN_TEST /* can be externally provided */ +# if (defined(_MSC_VER) && !defined(_M_X64)) +# define LZ4_ALIGN_TEST 0 /* disable on win32+visual */ +# else +# define LZ4_ALIGN_TEST 1 +# endif +#endif + /*-************************************ * Memory routines @@ -243,6 +257,11 @@ static const int LZ4_minLength = (MFLIMIT+1); # define DEBUGLOG(l, ...) {} /* disabled */ #endif +static int LZ4_isAligned(const void* ptr, size_t alignment) +{ + return ((size_t)ptr & (alignment -1)) == 0; +} + /*-************************************ * Types @@ -1406,26 +1425,22 @@ LZ4_stream_t* LZ4_createStream(void) return lz4s; } -#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : - it reports an aligment of 8-bytes, - while actually aligning LZ4_stream_t on 4 bytes. */ static size_t LZ4_stream_t_alignment(void) { +#if LZ4_ALIGN_TEST typedef struct { char c; LZ4_stream_t t; } t_a; return sizeof(t_a) - sizeof(LZ4_stream_t); -} +#else + return 1; /* effectively disabled */ #endif +} LZ4_stream_t* LZ4_initStream (void* buffer, size_t size) { DEBUGLOG(5, "LZ4_initStream"); if (buffer == NULL) { return NULL; } if (size < sizeof(LZ4_stream_t)) { return NULL; } -#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 : - it reports an aligment of 8-bytes, - while actually aligning LZ4_stream_t on 4 bytes. */ - if (((size_t)buffer) & (LZ4_stream_t_alignment() - 1)) { return NULL; } /* alignment check */ -#endif + if (!LZ4_isAligned(buffer, LZ4_stream_t_alignment())) return NULL; MEM_INIT(buffer, 0, sizeof(LZ4_stream_t)); return (LZ4_stream_t*)buffer; } diff --git a/lib/lz4hc.c b/lib/lz4hc.c index cf03eba..29b6073 100644 --- a/lib/lz4hc.c +++ b/lib/lz4hc.c @@ -75,15 +75,6 @@ typedef enum { noDictCtx, usingDictCtxHc } dictCtx_directive; #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) #define LZ4_OPT_NUM (1<<12) -/* for some reason, Visual Studio fails the aligment test on 32-bit x86 : - * it reports an aligment of 8-bytes, - * while LZ4_streamHC_t only requires alignment of 4-bytes - * resulting in initialization error when allocating state with malloc() */ -#if (defined(_MSC_VER) && !defined(_M_X64)) -# define LZ4_ALIGN_TEST 0 -#else -# define LZ4_ALIGN_TEST 1 -#endif /*=== Macros ===*/ #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) @@ -921,23 +912,22 @@ LZ4HC_compress_generic ( int LZ4_sizeofStateHC(void) { return (int)sizeof(LZ4_streamHC_t); } -#if LZ4_ALIGN_TEST static size_t LZ4_streamHC_t_alignment(void) { +#if LZ4_ALIGN_TEST typedef struct { char c; LZ4_streamHC_t t; } t_a; return sizeof(t_a) - sizeof(LZ4_streamHC_t); -} +#else + return 1; /* effectively disabled */ #endif +} /* state is presumed correctly initialized, * in which case its size and alignment have already been validate */ int LZ4_compress_HC_extStateHC_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel) { LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; -#if LZ4_ALIGN_TEST - assert(((size_t)state & (LZ4_streamHC_t_alignment() - 1)) == 0); /* check alignment */ -#endif - if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ + if (!LZ4_isAligned(state, LZ4_streamHC_t_alignment())) return 0; LZ4_resetStreamHC_fast((LZ4_streamHC_t*)state, compressionLevel); LZ4HC_init_internal (ctx, (const BYTE*)src); if (dstCapacity < LZ4_compressBound(srcSize)) @@ -1008,9 +998,7 @@ LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size) LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer; if (buffer == NULL) return NULL; if (size < sizeof(LZ4_streamHC_t)) return NULL; -#if LZ4_ALIGN_TEST - if (((size_t)buffer) & (LZ4_streamHC_t_alignment() - 1)) return NULL; /* alignment check */ -#endif + if (!LZ4_isAligned(buffer, LZ4_streamHC_t_alignment())) return NULL; /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE); DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", LZ4_streamHCPtr, (unsigned)size); |