Simplify C++ dynamic object initialization

Wrap DetectArmFeatures and DetectX86Features in InitializeCpu class
Use init_priority for InitializeCpu
Remove HAVE_GCC_CONSTRUCTOR1 and HAVE_GCC_CONSTRUCTOR0
Use init_seg(<name>) on Windows and explicitly insert at XCU segment
Simplify logic for HAVE_GAS
Remove special recipies for MACPORTS_GCC_COMPILER
Move C++ static initializers into anonymous namespace when possible
Add default NullNameValuePairs ctor for Clang
pull/398/head
Jeffrey Walton 2017-03-20 08:51:10 -04:00
parent 0c6510b0a5
commit f502ee9218
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
5 changed files with 112 additions and 110 deletions

View File

@ -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

View File

@ -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

42
cpu.cpp
View File

@ -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<InitializeCpu>().Ref();
#endif
ANONYMOUS_NAMESPACE_END
#endif // CRYPTOPP_IMPORTS

View File

@ -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<const NameValuePairs&>(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<const NameValuePairs&>(s_nullNameValuePairs);
#pragma warning(default: 4073)
#else
const std::string DEFAULT_CHANNEL = "";
const std::string AAD_CHANNEL = "AAD";
const simple_ptr<NullNameValuePairs> 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<const NameValuePairs&>(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<const NameValuePairs&>(s_nullNameValuePairs);
#pragma warning(default: 4075)
#else
const std::string DEFAULT_CHANNEL = "";
const std::string AAD_CHANNEL = "AAD";
const simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs);
const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;
#endif
NAMESPACE_END // CryptoPP
#endif // CRYPTOPP_IMPORTS

View File

@ -69,6 +69,8 @@
# define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86))
#endif
// ***************** C++ Static Initialization ********************
NAMESPACE_BEGIN(CryptoPP)
template <long i>
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<InitializeInteger>().Ref();
const CryptoPP::Integer& s_zero = CryptoPP::Singleton<CryptoPP::Integer, CryptoPP::NewInteger<0L> >().Ref();
@ -114,6 +116,8 @@ const CryptoPP::Integer& s_two = CryptoPP::Singleton<CryptoPP::Integer, CryptoP
#endif
ANONYMOUS_NAMESPACE_END
// ***************** Library code ********************
NAMESPACE_BEGIN(CryptoPP)
bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt)
@ -2114,13 +2118,7 @@ static PMul s_pMul[9], s_pBot[9];
static PSqu s_pSqu[9];
static PMulTop s_pTop[9];
#if HAVE_GCC_CONSTRUCTOR1
void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 35))) SetFunctionPointers()
#elif HAVE_GCC_CONSTRUCTOR0
void __attribute__ ((constructor)) SetFunctionPointers()
#else
void SetFunctionPointers()
#endif
{
s_pMul[0] = &Baseline_Multiply2;
s_pBot[0] = &Baseline_MultiplyBottom2;