From 073d54ae8351b25fb177b19531425de30670cb7f Mon Sep 17 00:00:00 2001 From: afresh1 Date: Tue, 16 Feb 2021 02:12:52 +0000 Subject: [PATCH] Backport upstream perl 64bit hash alignment fixes Different flags triggering new compiler optimizations means that luck has run out on this working by chance with the strict alignment of octeon. Upstream issue: https://github.com/Perl/perl5/issues/18555 This is a combination of three commits from upstream. https://github.com/Perl/perl5/commit/d18575f18c6ee61ce80492e82cae7361358d570a https://github.com/Perl/perl5/commit/6027b190154088fbbcbde08a80c49531e4e4c012 https://github.com/Perl/perl5/commit/f43079cb514e3d0be0036424695438ae3fb58451 works on all arch deraadt@ --- gnu/usr.bin/perl/hv_func.h | 58 ++++++++++++++++++---------- gnu/usr.bin/perl/perlvars.h | 4 +- gnu/usr.bin/perl/t/porting/libperl.t | 2 +- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/gnu/usr.bin/perl/hv_func.h b/gnu/usr.bin/perl/hv_func.h index 151aead9bf3..56585060a5a 100644 --- a/gnu/usr.bin/perl/hv_func.h +++ b/gnu/usr.bin/perl/hv_func.h @@ -36,27 +36,35 @@ #if defined(PERL_HASH_FUNC_SIPHASH) # define __PERL_HASH_FUNC "SIPHASH_2_4" -# define __PERL_HASH_SEED_BYTES 16 -# define __PERL_HASH_STATE_BYTES 32 +# define __PERL_HASH_WORD_TYPE U64 +# define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE) +# define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 2) +# define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 4) # define __PERL_HASH_SEED_STATE(seed,state) S_perl_siphash_seed_state(seed,state) # define __PERL_HASH_WITH_STATE(state,str,len) S_perl_hash_siphash_2_4_with_state((state),(U8*)(str),(len)) #elif defined(PERL_HASH_FUNC_SIPHASH13) # define __PERL_HASH_FUNC "SIPHASH_1_3" -# define __PERL_HASH_SEED_BYTES 16 -# define __PERL_HASH_STATE_BYTES 32 +# define __PERL_HASH_WORD_TYPE U64 +# define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE) +# define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 2) +# define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 4) # define __PERL_HASH_SEED_STATE(seed,state) S_perl_siphash_seed_state(seed,state) # define __PERL_HASH_WITH_STATE(state,str,len) S_perl_hash_siphash_1_3_with_state((state),(U8*)(str),(len)) #elif defined(PERL_HASH_FUNC_STADTX) # define __PERL_HASH_FUNC "STADTX" -# define __PERL_HASH_SEED_BYTES 16 -# define __PERL_HASH_STATE_BYTES 32 +# define __PERL_HASH_WORD_TYPE U64 +# define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE) +# define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 2) +# define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 4) # define __PERL_HASH_SEED_STATE(seed,state) stadtx_seed_state(seed,state) # define __PERL_HASH_WITH_STATE(state,str,len) (U32)stadtx_hash_with_state((state),(U8*)(str),(len)) # include "stadtx_hash.h" #elif defined(PERL_HASH_FUNC_ZAPHOD32) # define __PERL_HASH_FUNC "ZAPHOD32" -# define __PERL_HASH_SEED_BYTES 12 -# define __PERL_HASH_STATE_BYTES 12 +# define __PERL_HASH_WORD_TYPE U32 +# define __PERL_HASH_WORD_SIZE sizeof(__PERL_HASH_WORD_TYPE) +# define __PERL_HASH_SEED_BYTES (__PERL_HASH_WORD_SIZE * 3) +# define __PERL_HASH_STATE_BYTES (__PERL_HASH_WORD_SIZE * 3) # define __PERL_HASH_SEED_STATE(seed,state) zaphod32_seed_state(seed,state) # define __PERL_HASH_WITH_STATE(state,str,len) (U32)zaphod32_hash_with_state((state),(U8*)(str),(len)) # include "zaphod32_hash.h" @@ -73,6 +81,12 @@ #endif +#define __PERL_HASH_SEED_roundup(x, y) ( ( ( (x) + ( (y) - 1 ) ) / (y) ) * (y) ) +#define _PERL_HASH_SEED_roundup(x) __PERL_HASH_SEED_roundup(x,__PERL_HASH_WORD_SIZE) + +#define PL_hash_seed ((U8 *)PL_hash_seed_w) +#define PL_hash_state ((U8 *)PL_hash_state_w) + #if PERL_HASH_USE_SBOX32_ALSO != 1 # define _PERL_HASH_FUNC __PERL_HASH_FUNC # define _PERL_HASH_SEED_BYTES __PERL_HASH_SEED_BYTES @@ -82,9 +96,8 @@ #else #define _PERL_HASH_FUNC "SBOX32_WITH_" __PERL_HASH_FUNC - -#define _PERL_HASH_SEED_roundup(x, y) ((((x)+((y)-1))/(y))*(y)) -#define _PERL_HASH_SEED_BYTES ( _PERL_HASH_SEED_roundup(__PERL_HASH_SEED_BYTES + (int)( 3 * sizeof(U32)), sizeof(U64) ) ) +/* note the 3 in the below code comes from the fact the seed to initialize the SBOX is 96 bits */ +#define _PERL_HASH_SEED_BYTES ( __PERL_HASH_SEED_BYTES + (int)( 3 * sizeof(U32)) ) #define _PERL_HASH_STATE_BYTES \ ( __PERL_HASH_STATE_BYTES + ( ( 1 + ( 256 * SBOX32_MAX_LEN ) ) * sizeof(U32) ) ) @@ -101,23 +114,19 @@ #endif -PERL_STATIC_INLINE -U32 S_perl_hash_with_seed(const U8 * const seed, const U8 * const str, const STRLEN len) -{ - U8 state[_PERL_HASH_STATE_BYTES]; - _PERL_HASH_SEED_STATE(seed,state); - return _PERL_HASH_WITH_STATE(state,str,len); -} - #define PERL_HASH_WITH_SEED(seed,hash,str,len) \ (hash) = S_perl_hash_with_seed((const U8 *) seed, (const U8 *) str,len) #define PERL_HASH_WITH_STATE(state,hash,str,len) \ (hash) = _PERL_HASH_WITH_STATE((state),(U8*)(str),(len)) + #define PERL_HASH_SEED_STATE(seed,state) _PERL_HASH_SEED_STATE(seed,state) -#define PERL_HASH_SEED_BYTES _PERL_HASH_SEED_BYTES -#define PERL_HASH_STATE_BYTES _PERL_HASH_STATE_BYTES +#define PERL_HASH_SEED_BYTES _PERL_HASH_SEED_roundup(_PERL_HASH_SEED_BYTES) +#define PERL_HASH_STATE_BYTES _PERL_HASH_SEED_roundup(_PERL_HASH_STATE_BYTES) #define PERL_HASH_FUNC _PERL_HASH_FUNC +#define PERL_HASH_SEED_WORDS (PERL_HASH_SEED_BYTES/__PERL_HASH_WORD_SIZE) +#define PERL_HASH_STATE_WORDS (PERL_HASH_STATE_BYTES/__PERL_HASH_WORD_SIZE) + #ifdef PERL_USE_SINGLE_CHAR_HASH_CACHE #define PERL_HASH(state,str,len) \ (hash) = ((len) < 2 ? ( (len) == 0 ? PL_hash_chars[256] : PL_hash_chars[(U8)(str)[0]] ) \ @@ -271,6 +280,13 @@ PERL_SIPHASH_FNC( #endif /* defined(CAN64BITHASH) */ +PERL_STATIC_INLINE U32 +S_perl_hash_with_seed(const U8 * seed, const U8 *str, STRLEN len) { + __PERL_HASH_WORD_TYPE state[PERL_HASH_STATE_WORDS]; + _PERL_HASH_SEED_STATE(seed,(U8*)state); + return _PERL_HASH_WITH_STATE((U8*)state,str,len); +} + #endif /*compile once*/ /* diff --git a/gnu/usr.bin/perl/perlvars.h b/gnu/usr.bin/perl/perlvars.h index 466c515ebb5..e1113ac64c4 100644 --- a/gnu/usr.bin/perl/perlvars.h +++ b/gnu/usr.bin/perl/perlvars.h @@ -255,9 +255,9 @@ PERLVAR(G, malloc_mutex, perl_mutex) /* Mutex for malloc */ #endif PERLVARI(G, hash_seed_set, bool, FALSE) /* perl.c */ -PERLVARA(G, hash_seed, PERL_HASH_SEED_BYTES, unsigned char) /* perl.c and hv.h */ +PERLVARA(G, hash_seed_w, PERL_HASH_SEED_WORDS, __PERL_HASH_WORD_TYPE) /* perl.c and hv.h */ #if defined(PERL_HASH_STATE_BYTES) -PERLVARA(G, hash_state, PERL_HASH_STATE_BYTES, unsigned char) /* perl.c and hv.h */ +PERLVARA(G, hash_state_w, PERL_HASH_STATE_WORDS, __PERL_HASH_WORD_TYPE) /* perl.c and hv.h */ #endif #if defined(PERL_USE_SINGLE_CHAR_HASH_CACHE) PERLVARA(G, hash_chars, (1+256) * sizeof(U32), unsigned char) /* perl.c and hv.h */ diff --git a/gnu/usr.bin/perl/t/porting/libperl.t b/gnu/usr.bin/perl/t/porting/libperl.t index 72b4220c6a6..dbfb309e3f9 100644 --- a/gnu/usr.bin/perl/t/porting/libperl.t +++ b/gnu/usr.bin/perl/t/porting/libperl.t @@ -444,7 +444,7 @@ if ($GSP) { $symbols{data}{common} = $symbols{data}{bss}; } - ok($symbols{data}{common}{PL_hash_seed}{'globals.o'}, "has PL_hash_seed"); + ok($symbols{data}{common}{PL_hash_seed_w}{'globals.o'}, "has PL_hash_seed_w"); ok($symbols{data}{data}{PL_ppaddr}{'globals.o'}, "has PL_ppaddr"); # None of the GLOBAL_STRUCT* business here. -- 2.20.1