diff --git a/GNUmakefile b/GNUmakefile index ff2393bc..450db26c 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -122,15 +122,18 @@ ifneq ($(HAS_NEWLIB),0) endif endif +# Clang integrated assembler will be used with -Wa,-q +CLANG_INTEGRATED_ASSEMBLER ?= 0 + ########################################################### ##### X86/X32/X64 Options ##### ########################################################### ifneq ($(IS_X86)$(IS_X32)$(IS_X64),000) -# Fixup. Clang integrated assembler will be used (-Wa,-q) +# Fixup. Clang reports an error rather than "LLVM assembler" or similar. ifneq ($(MACPORTS_COMPILER),1) - IS_GAS := $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler") + HAVE_GAS := $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler") endif ifneq ($(GCC_COMPILER),0) @@ -139,7 +142,7 @@ ifneq ($(GCC_COMPILER),0) GCC46_OR_LATER := $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "gcc version (4\.[6-9]|[5-9]\.)") endif -ifneq ($(IS_GAS),0) +ifneq ($(HAVE_GAS),0) GAS210_OR_LATER := $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.[1-9][0-9]|[3-9])") GAS217_OR_LATER := $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.1[7-9]|2\.[2-9]|[3-9])") GAS219_OR_LATER := $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.19|2\.[2-9]|[3-9])") @@ -205,19 +208,6 @@ CXXFLAGS += -DCRYPTOPP_DISABLE_ASM endif endif -# .intel_syntax wasn't supported until GNU assembler 2.10 -ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER)$(GAS210_OR_LATER),100) -CXXFLAGS += -DCRYPTOPP_DISABLE_ASM -else -ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER)$(GAS217_OR_LATER),100) -CXXFLAGS += -DCRYPTOPP_DISABLE_SSSE3 -else -ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER)$(GAS219_OR_LATER),100) -CXXFLAGS += -DCRYPTOPP_DISABLE_AESNI -endif -endif -endif - # Tell MacPorts GCC to use Clang integrated assembler # http://github.com/weidai11/cryptopp/issues/190 ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER),11) @@ -225,10 +215,24 @@ ifeq ($(findstring -Wa,-q,$(CXXFLAGS)),) CXXFLAGS += -Wa,-q endif ifeq ($(findstring -DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER,$(CXXFLAGS)),) +CLANG_INTEGRATED_ASSEMBLER := 1 CXXFLAGS += -DCRYPTOPP_CLANG_INTEGRATED_ASSEMBLER=1 endif endif +# .intel_syntax wasn't supported until GNU assembler 2.10 +ifeq ($(HAVE_GAS)$(GAS210_OR_LATER),10) +CXXFLAGS += -DCRYPTOPP_DISABLE_ASM +else +ifeq ($(HAVE_GAS)$(GAS217_OR_LATER),10) +CXXFLAGS += -DCRYPTOPP_DISABLE_SSSE3 +else +ifeq ($(HAVE_GAS)$(GAS219_OR_LATER),10) +CXXFLAGS += -DCRYPTOPP_DISABLE_AESNI +endif +endif +endif + # GCC on Solaris needs -m64. Otherwise, i386 is default # http://github.com/weidai11/cryptopp/issues/230 ifeq ($(IS_SUN)$(GCC_COMPILER)$(IS_X64),111) @@ -754,17 +758,6 @@ ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps) -include GNUmakefile.deps endif # Dependencies -# MacPorts/GCC issue with init_priority. Apple/GCC and Fink/GCC are fine; limit to MacPorts. -# Also see http://lists.macosforge.org/pipermail/macports-users/2015-September/039223.html -ifeq ($(GCC_COMPILER)$(MACPORTS_COMPILER),11) -ifeq ($(findstring -DMACPORTS_GCC_COMPILER, $(strip $(CXXFLAGS))),) -cryptlib.o: - $(CXX) $(strip $(CXXFLAGS)) -DMACPORTS_GCC_COMPILER=1 -c cryptlib.cpp -cpu.o: - $(CXX) $(strip $(CXXFLAGS)) -DMACPORTS_GCC_COMPILER=1 -c cpu.cpp -endif -endif - # Run rdrand-nasm.sh to create the object files ifeq ($(USE_NASM),1) rdrand.o: rdrand.h rdrand.cpp rdrand.S diff --git a/config.h b/config.h index 4acb6419..cfa3a9b6 100644 --- a/config.h +++ b/config.h @@ -125,44 +125,6 @@ # define CRYPTOPP_DEBUG 1 #endif -// ***************** Initialization and Constructor priorities ******************** - -// MacPorts/GCC and Solaris/GCC does not provide constructor(priority). Apple/GCC and Fink/GCC do provide it. -// See http://cryptopp.com/wiki/Static_Initialization_Order_Fiasco - -// CRYPTOPP_INIT_PRIORITY attempts to manage initialization of C++ static objects. -// Under GCC, the library uses init_priority attribute in the range -// [CRYPTOPP_INIT_PRIORITY, CRYPTOPP_INIT_PRIORITY+100]. Under Windows, -// CRYPTOPP_INIT_PRIORITY enlists "#pragma init_seg(lib)". -#ifndef CRYPTOPP_INIT_PRIORITY -# define CRYPTOPP_INIT_PRIORITY 250 -#endif - -// CRYPTOPP_USER_PRIORITY is for other libraries and user code that is using Crypto++ -// and managing C++ static object creation. It is guaranteed not to conflict with -// values used by (or would be used by) the Crypto++ library. -#if defined(CRYPTOPP_INIT_PRIORITY) && (CRYPTOPP_INIT_PRIORITY > 0) -# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY + 101) -#else -# define CRYPTOPP_USER_PRIORITY 350 -#endif - -// __attribute__(init_priority(250)) is supported -#if (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0) && !defined(__sun__)) -# define HAVE_GCC_INIT_PRIORITY 1 -# define HAVE_GCC_CONSTRUCTOR1 1 -#endif - -// __attribute__(init_priority()) is supported -#if (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !HAVE_GCC_CONSTRUCTOR1 && !(MACPORTS_GCC_COMPILER > 0) && !defined(__sun__)) -# define HAVE_GCC_INIT_PRIORITY 1 -# define HAVE_GCC_CONSTRUCTOR0 1 -#endif - -#if (_MSC_VER && (CRYPTOPP_INIT_PRIORITY > 0)) -# define HAVE_MSC_INIT_PRIORITY 1 -#endif - // ***************** Important Settings Again ******************** // But the defaults should be ok. @@ -605,6 +567,36 @@ NAMESPACE_END #endif #endif +// ***************** Initialization and Constructor priorities ******************** + +// CRYPTOPP_INIT_PRIORITY attempts to manage initialization of C++ static objects. +// Under GCC, the library uses init_priority attribute in the range +// [CRYPTOPP_INIT_PRIORITY, CRYPTOPP_INIT_PRIORITY+100]. Under Windows, +// CRYPTOPP_INIT_PRIORITY enlists "#pragma init_seg(lib)". The platforms +// with gaps are Apple and Sun because they require linker scripts. Apple and +// Sun will use the library's Singletons to initialize and acquire resources. +// Also see http://cryptopp.com/wiki/Static_Initialization_Order_Fiasco +#ifndef CRYPTOPP_INIT_PRIORITY +# define CRYPTOPP_INIT_PRIORITY 250 +#endif + +// CRYPTOPP_USER_PRIORITY is for other libraries and user code that is using Crypto++ +// and managing C++ static object creation. It is guaranteed not to conflict with +// values used by (or would be used by) the Crypto++ library. +#if defined(CRYPTOPP_INIT_PRIORITY) && (CRYPTOPP_INIT_PRIORITY > 0) +# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY + 101) +#else +# define CRYPTOPP_USER_PRIORITY 350 +#endif + +#if (CRYPTOPP_INIT_PRIORITY > 0) && !(defined(__APPLE__) || defined(__sun__)) +# if (CRYPTOPP_GCC_VERSION >= 30000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 800) +# define HAVE_GCC_INIT_PRIORITY 1 +# elif (CRYPTOPP_MSC_VERSION >= 1310) +# define HAVE_MSC_INIT_PRIORITY 1 +# endif +#endif // CRYPTOPP_INIT_PRIORITY, Sun, Darwin + // ***************** determine availability of OS features ******************** #ifndef NO_OS_DEPENDENCE diff --git a/cpu.cpp b/cpu.cpp index 62e12fe2..f5822600 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -216,13 +216,7 @@ static inline bool IsVIA(const word32 output[4]) (output[3] /*EDX*/ == 0x48727561); } -#if HAVE_GCC_CONSTRUCTOR1 -void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 20))) DetectX86Features() -#elif HAVE_GCC_CONSTRUCTOR0 -void __attribute__ ((constructor)) DetectX86Features() -#else void DetectX86Features() -#endif { // Coverity finding CID 171239... word32 cpuid1[4]={0}, cpuid2[4]={0}, cpuid3[4]={0}; @@ -729,13 +723,7 @@ static bool TrySHA2() #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE } -#if HAVE_GCC_CONSTRUCTOR1 -void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 20))) DetectArmFeatures() -#elif HAVE_GCC_CONSTRUCTOR0 -void __attribute__ ((constructor)) DetectArmFeatures() -#else void DetectArmFeatures() -#endif { g_hasNEON = TryNEON(); g_hasPMULL = TryPMULL(); @@ -744,11 +732,37 @@ void DetectArmFeatures() g_hasSHA1 = TrySHA1(); g_hasSHA2 = TrySHA2(); - *((volatile bool*)&g_ArmDetectionDone) = true; + g_ArmDetectionDone = true; } #endif - NAMESPACE_END +// ***************** C++ Static Initialization ******************** + +ANONYMOUS_NAMESPACE_BEGIN +struct InitializeCpu +{ + InitializeCpu() + { +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + CryptoPP::DetectX86Features(); +#elif CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64 + CryptoPP::DetectArmFeatures(); #endif + } +}; + +#if HAVE_GCC_INIT_PRIORITY +const InitializeCpu s_init __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 20))) = InitializeCpu(); +#elif HAVE_MSC_INIT_PRIORITY +#pragma warning(disable: 4075) +#pragma init_seg(".CRT$XCU-020") +const InitializeCpu s_init; +#pragma warning(default: 4075) +#else +const InitializeCpu& s_init = CryptoPP::Singleton().Ref(); +#endif +ANONYMOUS_NAMESPACE_END + +#endif // CRYPTOPP_IMPORTS diff --git a/cryptlib.cpp b/cryptlib.cpp index 189f7759..19ea1c6a 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -45,31 +45,11 @@ CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word)); class NullNameValuePairs : public NameValuePairs { public: - NullNameValuePairs() {} // Clang complaint a default ctor must be avilable + NullNameValuePairs() {} // Clang complains a default ctor must be avilable bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {CRYPTOPP_UNUSED(name); CRYPTOPP_UNUSED(valueType); CRYPTOPP_UNUSED(pValue); return false;} }; -#if HAVE_GCC_INIT_PRIORITY -const std::string DEFAULT_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 10))) = ""; -const std::string AAD_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 11))) = "AAD"; -const NullNameValuePairs s_nullNameValuePairs __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 12))); -const NameValuePairs &g_nullNameValuePairs = dynamic_cast(s_nullNameValuePairs); -#elif HAVE_MSC_INIT_PRIORITY -#pragma warning(disable: 4073) -#pragma init_seg(lib) -const std::string DEFAULT_CHANNEL = ""; -const std::string AAD_CHANNEL = "AAD"; -const NullNameValuePairs s_nullNameValuePairs; -const NameValuePairs &g_nullNameValuePairs = dynamic_cast(s_nullNameValuePairs); -#pragma warning(default: 4073) -#else -const std::string DEFAULT_CHANNEL = ""; -const std::string AAD_CHANNEL = "AAD"; -const simple_ptr s_pNullNameValuePairs(new NullNameValuePairs); -const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p; -#endif - BufferedTransformation & TheBitBucket() { static BitBucket bitBucket; @@ -948,6 +928,31 @@ int LibraryVersion(CRYPTOPP_NOINLINE_DOTDOTDOT) { return CRYPTOPP_BUILD_VERSION; } -NAMESPACE_END +// ***************** C++ Static Initialization ******************** +// We can't put these in the anonymous namespace. DEFAULT_CHANNEL, +// AAD_CHANNEL and g_nullNameValuePairs must be defined in CryptoPP. + +#if HAVE_GCC_INIT_PRIORITY +const std::string DEFAULT_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 10))) = ""; +const std::string AAD_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 11))) = "AAD"; +const NullNameValuePairs s_nullNameValuePairs __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 12))); +const NameValuePairs &g_nullNameValuePairs = dynamic_cast(s_nullNameValuePairs); +#elif HAVE_MSC_INIT_PRIORITY +#pragma warning(disable: 4075) +#pragma init_seg(".CRT$XCU-010") +const std::string DEFAULT_CHANNEL(""); +const std::string AAD_CHANNEL("AAD"); +const NullNameValuePairs s_nullNameValuePairs; +const NameValuePairs &g_nullNameValuePairs = dynamic_cast(s_nullNameValuePairs); +#pragma warning(default: 4075) +#else +const std::string DEFAULT_CHANNEL = ""; +const std::string AAD_CHANNEL = "AAD"; +const simple_ptr s_pNullNameValuePairs(new NullNameValuePairs); +const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p; #endif + +NAMESPACE_END // CryptoPP + +#endif // CRYPTOPP_IMPORTS diff --git a/integer.cpp b/integer.cpp index 2ee9d80f..700e8902 100644 --- a/integer.cpp +++ b/integer.cpp @@ -69,6 +69,8 @@ # define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86)) #endif +// ***************** C++ Static Initialization ******************** + NAMESPACE_BEGIN(CryptoPP) template struct NewInteger @@ -99,13 +101,13 @@ const CryptoPP::Integer s_zero __attribute__ ((init_priority (CRYPTOPP_INIT_PRIO const CryptoPP::Integer s_one __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 32))) = CryptoPP::Integer(1L); const CryptoPP::Integer s_two __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 33))) = CryptoPP::Integer(2L); #elif HAVE_MSC_INIT_PRIORITY -#pragma warning(disable: 4073) -#pragma init_seg(lib) +#pragma warning(disable: 4075) +#pragma init_seg(".CRT$XCU-030") const InitializeInteger s_init; const CryptoPP::Integer s_zero(0L); const CryptoPP::Integer s_one(1L); const CryptoPP::Integer s_two(2L); -#pragma warning(default: 4073) +#pragma warning(default: 4075) #else const InitializeInteger& s_init = CryptoPP::Singleton().Ref(); const CryptoPP::Integer& s_zero = CryptoPP::Singleton >().Ref(); @@ -114,6 +116,8 @@ const CryptoPP::Integer& s_two = CryptoPP::Singleton