Rework Glibc sysconf code

It looks like the 0 return value for _SC_LEVEL1_DCACHE_LINESIZE is not a 1-off problem with PPC. It appears Glibc regularly returns 0 instead of failure. Also see https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c.
We were OK before the change. The difference now is, we expect all Glibc queries to misbehave
pull/603/head
Jeffrey Walton 2018-03-21 16:19:43 -04:00
parent ddf9e70234
commit f589de0839
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 60 additions and 57 deletions

117
cpu.cpp
View File

@ -31,10 +31,10 @@
# include <sys/auxv.h> # include <sys/auxv.h>
#else #else
#ifndef AT_HWCAP #ifndef AT_HWCAP
#define AT_HWCAP 16 # define AT_HWCAP 16
#endif #endif
#ifndef AT_HWCAP2 #ifndef AT_HWCAP2
#define AT_HWCAP2 26 # define AT_HWCAP2 26
#endif #endif
unsigned long int getauxval(unsigned long int) { return 0; } unsigned long int getauxval(unsigned long int) { return 0; }
#endif #endif
@ -299,7 +299,7 @@ void DetectX86Features()
} }
} }
if (!g_cacheLineSize) if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_x86DetectionDone) = true; *const_cast<volatile bool*>(&g_x86DetectionDone) = true;
@ -374,21 +374,21 @@ extern bool CPU_ProbePMULL();
inline bool CPU_QueryNEON() inline bool CPU_QueryNEON()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD)) ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0))
return true; return true;
#elif defined(__ANDROID__) && defined(__arm__) #elif defined(__ANDROID__) && defined(__arm__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0))
return true; return true;
#elif defined(__linux__) && defined(__aarch64__) #elif defined(__linux__) && defined(__aarch64__)
if (getauxval(AT_HWCAP) & HWCAP_ASIMD) if ((getauxval(AT_HWCAP) & HWCAP_ASIMD) != 0)
return true; return true;
#elif defined(__linux__) && defined(__aarch32__) #elif defined(__linux__) && defined(__aarch32__)
if (getauxval(AT_HWCAP2) & HWCAP2_ASIMD) if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0)
return true; return true;
#elif defined(__linux__) && defined(__arm__) #elif defined(__linux__) && defined(__arm__)
if (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) if ((getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// Core feature set for Aarch32 and Aarch64. // Core feature set for Aarch32 and Aarch64.
@ -400,18 +400,18 @@ inline bool CPU_QueryNEON()
inline bool CPU_QueryCRC32() inline bool CPU_QueryCRC32()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32)) ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32) != 0))
return true; return true;
#elif defined(__ANDROID__) && defined(__aarch32__) #elif defined(__ANDROID__) && defined(__aarch32__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0)&&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32) != 0))
return true; return true;
#elif defined(__linux__) && defined(__aarch64__) #elif defined(__linux__) && defined(__aarch64__)
if (getauxval(AT_HWCAP) & HWCAP_CRC32) if ((getauxval(AT_HWCAP) & HWCAP_CRC32) != 0)
return true; return true;
#elif defined(__linux__) && defined(__aarch32__) #elif defined(__linux__) && defined(__aarch32__)
if (getauxval(AT_HWCAP2) & HWCAP2_CRC32) if ((getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// No compiler support. CRC intrinsics result in a failed compiled. // No compiler support. CRC intrinsics result in a failed compiled.
@ -423,18 +423,18 @@ inline bool CPU_QueryCRC32()
inline bool CPU_QueryPMULL() inline bool CPU_QueryPMULL()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0)&&
(android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL)) ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL) != 0))
return true; return true;
#elif defined(__ANDROID__) && defined(__aarch32__) #elif defined(__ANDROID__) && defined(__aarch32__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL) != 0))
return true; return true;
#elif defined(__linux__) && defined(__aarch64__) #elif defined(__linux__) && defined(__aarch64__)
if (getauxval(AT_HWCAP) & HWCAP_PMULL) if ((getauxval(AT_HWCAP) & HWCAP_PMULL) != 0)
return true; return true;
#elif defined(__linux__) && defined(__aarch32__) #elif defined(__linux__) && defined(__aarch32__)
if (getauxval(AT_HWCAP2) & HWCAP2_PMULL) if ((getauxval(AT_HWCAP2) & HWCAP2_PMULL) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// No compiler support. PMULL intrinsics result in a failed compiled. // No compiler support. PMULL intrinsics result in a failed compiled.
@ -446,18 +446,18 @@ inline bool CPU_QueryPMULL()
inline bool CPU_QueryAES() inline bool CPU_QueryAES()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0)&&
(android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES)) ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES) != 0))
return true; return true;
#elif defined(__ANDROID__) && defined(__aarch32__) #elif defined(__ANDROID__) && defined(__aarch32__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0)&&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0))
return true; return true;
#elif defined(__linux__) && defined(__aarch64__) #elif defined(__linux__) && defined(__aarch64__)
if (getauxval(AT_HWCAP) & HWCAP_AES) if ((getauxval(AT_HWCAP) & HWCAP_AES) != 0)
return true; return true;
#elif defined(__linux__) && defined(__aarch32__) #elif defined(__linux__) && defined(__aarch32__)
if (getauxval(AT_HWCAP2) & HWCAP2_AES) if ((getauxval(AT_HWCAP2) & HWCAP2_AES) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
@ -481,18 +481,18 @@ inline bool CPU_QueryAES()
inline bool CPU_QuerySHA1() inline bool CPU_QuerySHA1()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1)) ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1) != 0))
return true; return true;
#elif defined(__ANDROID__) && defined(__aarch32__) #elif defined(__ANDROID__) && defined(__aarch32__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1) != 0))
return true; return true;
#elif defined(__linux__) && defined(__aarch64__) #elif defined(__linux__) && defined(__aarch64__)
if (getauxval(AT_HWCAP) & HWCAP_SHA1) if ((getauxval(AT_HWCAP) & HWCAP_SHA1) != 0)
return true; return true;
#elif defined(__linux__) && defined(__aarch32__) #elif defined(__linux__) && defined(__aarch32__)
if (getauxval(AT_HWCAP2) & HWCAP2_SHA1) if ((getauxval(AT_HWCAP2) & HWCAP2_SHA1) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
@ -516,18 +516,18 @@ inline bool CPU_QuerySHA1()
inline bool CPU_QuerySHA2() inline bool CPU_QuerySHA2()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0)&&
(android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2)) ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2) != 0))
return true; return true;
#elif defined(__ANDROID__) && defined(__aarch32__) #elif defined(__ANDROID__) && defined(__aarch32__)
if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2) != 0))
return true; return true;
#elif defined(__linux__) && defined(__aarch64__) #elif defined(__linux__) && defined(__aarch64__)
if (getauxval(AT_HWCAP) & HWCAP_SHA2) if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0)
return true; return true;
#elif defined(__linux__) && defined(__aarch32__) #elif defined(__linux__) && defined(__aarch32__)
if (getauxval(AT_HWCAP2) & HWCAP2_SHA2) if ((getauxval(AT_HWCAP2) & HWCAP2_SHA2) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
@ -560,12 +560,13 @@ void DetectArmFeatures()
g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2(); g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2();
#if defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE) #if defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
g_cacheLineSize = sysconf(_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
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
if (cacheLineSize > 0)
g_cacheLineSize = cacheLineSize;
#endif #endif
if (!g_cacheLineSize)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_ArmDetectionDone) = true; *const_cast<volatile bool*>(&g_ArmDetectionDone) = true;
} }
@ -601,7 +602,7 @@ extern bool CPU_ProbeSHA512();
inline bool CPU_QueryAltivec() inline bool CPU_QueryAltivec()
{ {
#if defined(__linux__) #if defined(__linux__)
if (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
if (__power_vmx() != 0) if (__power_vmx() != 0)
@ -626,7 +627,7 @@ inline bool CPU_QueryPower7()
{ {
// Power7 and ISA 2.06 // Power7 and ISA 2.06
#if defined(__linux__) #if defined(__linux__)
if (getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06 != 0) if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
if (__power_7_andup() != 0) if (__power_7_andup() != 0)
@ -639,7 +640,7 @@ inline bool CPU_QueryPower8()
{ {
// Power8 and ISA 2.07 provide in-core crypto. // Power8 and ISA 2.07 provide in-core crypto.
#if defined(__linux__) #if defined(__linux__)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07 != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
if (__power_8_andup() != 0) if (__power_8_andup() != 0)
@ -653,7 +654,7 @@ inline bool CPU_QueryAES()
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
if (__power_8_andup() != 0) if (__power_8_andup() != 0)
@ -667,7 +668,7 @@ inline bool CPU_QuerySHA256()
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
if (__power_8_andup() != 0) if (__power_8_andup() != 0)
@ -680,7 +681,7 @@ inline bool CPU_QuerySHA512()
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
if (__power_8_andup() != 0) if (__power_8_andup() != 0)
@ -701,17 +702,19 @@ void DetectPowerpcFeatures()
g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256(); g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256();
g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512(); g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512();
#if defined(_AIX) #if defined(_AIX) && defined(SC_L1C_DLS)
// /usr/include/sys/systemcfg.h // /usr/include/sys/systemcfg.h
g_cacheLineSize = getsystemcfg(SC_L1C_DLS); int cacheLineSize = getsystemcfg(SC_L1C_DLS);
if (cacheLineSize > 0)
g_cacheLineSize = cacheLineSize;
#elif defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE) #elif defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
// GCC112 CentOS 7 returns 0? // Glibc does not implement on some platforms. The runtime returns 0 instead of error.
g_cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
if (cacheLineSize > 0)
g_cacheLineSize = cacheLineSize;
#endif #endif
if (g_cacheLineSize <= 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_PowerpcDetectionDone) = true; *const_cast<volatile bool*>(&g_PowerpcDetectionDone) = true;
} }