Set g_x86DetectionDone when CRYPTOPP_DISABLE_ASM is in effect

Previously we were re-entering DetectX86Features when CpuId failed or CRYPTOPP_DISABLE_ASM was in effect
This commit is contained in:
Jeffrey Walton 2020-01-23 02:46:30 -05:00
parent 649648aba8
commit eb67356732
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
3 changed files with 28 additions and 22 deletions

View File

@ -165,10 +165,10 @@ endif
# Base CXXFLAGS used if the user did not specify them
ifeq ($(CXXFLAGS),)
ifeq ($(SUN_COMPILER),1)
CRYPTOPP_CXXFLAGS = -DNDEBUG -g -xO3
CRYPTOPP_CXXFLAGS += -DNDEBUG -g -xO3
ZOPT = -xO0
else
CRYPTOPP_CXXFLAGS = -DNDEBUG -g2 -O3
CRYPTOPP_CXXFLAGS += -DNDEBUG -g2 -O3
ZOPT = -O0
endif
endif

42
cpu.cpp
View File

@ -308,23 +308,33 @@ static inline bool IsVIA(const word32 output[4])
void DetectX86Features()
{
// Coverity finding CID 171239...
// Coverity finding CID 171239. Initialize arrays.
word32 cpuid0[4]={0}, cpuid1[4]={0}, cpuid2[4]={0};
if (!CpuId(0, 0, cpuid0))
return;
if (!CpuId(1, 0, cpuid1))
return;
// cpuid1[2] & (1 << 27) is XSAVE/XRESTORE and signals OS support for SSE; use it to avoid probes.
// See http://github.com/weidai11/cryptopp/issues/511 and http://stackoverflow.com/a/22521619/608639
#if defined(CRYPTOPP_DISABLE_ASM)
// Not available
goto done;
#else
if (!CpuId(0, 0, cpuid0))
goto done;
if (!CpuId(1, 0, cpuid1))
goto done;
#endif
// cpuid1[2] & (1 << 27) is XSAVE/XRESTORE and signals OS support for SSE;
// use it to avoid probes. See http://stackoverflow.com/a/22521619/608639
// and http://github.com/weidai11/cryptopp/issues/511.
if ((cpuid1[3] & (1 << 26)) != 0)
g_hasSSE2 = ((cpuid1[2] & (1 << 27)) != 0) || CPU_ProbeSSE2();
g_hasSSSE3 = g_hasSSE2 && ((cpuid1[2] & (1<< 9)) != 0);
g_hasSSE41 = g_hasSSE2 && ((cpuid1[2] & (1<<19)) != 0);
g_hasSSE42 = g_hasSSE2 && ((cpuid1[2] & (1<<20)) != 0);
g_hasAESNI = g_hasSSE2 && ((cpuid1[2] & (1<<25)) != 0);
g_hasCLMUL = g_hasSSE2 && ((cpuid1[2] & (1<< 1)) != 0);
if (g_hasSSE2 == false)
goto done;
g_hasSSSE3 = (cpuid1[2] & (1<< 9)) != 0;
g_hasSSE41 = (cpuid1[2] & (1<<19)) != 0;
g_hasSSE42 = (cpuid1[2] & (1<<20)) != 0;
g_hasAESNI = (cpuid1[2] & (1<<25)) != 0;
g_hasCLMUL = (cpuid1[2] & (1<< 1)) != 0;
// AVX is similar to SSE, but check both bits 27 (SSE) and 28 (AVX).
// https://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled
@ -333,12 +343,8 @@ void DetectX86Features()
if ((cpuid1[2] & AVX_FLAG) == AVX_FLAG)
{
// Unable to perform the necessary tests
#if defined(CRYPTOPP_DISABLE_ASM)
g_hasAVX = false;
// GCC 4.1/Binutils 2.17 cannot consume xgetbv
#elif defined(__GNUC__) || (__SUNPRO_CC >= 0x5100) || defined(__BORLANDC__)
#if defined(__GNUC__) || (__SUNPRO_CC >= 0x5100) || defined(__BORLANDC__)
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71659 and
// http://www.agner.org/optimize/vectorclass/read.php?i=65
word32 a=0, d=0;
@ -480,6 +486,8 @@ void DetectX86Features()
}
}
done:
#if defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c

4
cpu.h
View File

@ -115,9 +115,7 @@ CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 func, word32 subfunc, word32 output[
/// \note This function is only available on Intel IA-32 platforms
inline bool HasSSE2()
{
#if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32)
return true;
#elif (CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_SSE2_INTRIN_AVAILABLE)
#if (CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_SSE2_INTRIN_AVAILABLE)
if (!g_x86DetectionDone)
DetectX86Features();
return g_hasSSE2;