Index: lib/scudo/scudo_utils.cpp =================================================================== --- lib/scudo/scudo_utils.cpp +++ lib/scudo/scudo_utils.cpp @@ -13,15 +13,24 @@ #include "scudo_utils.h" -#include -#include +#include "sanitizer_common/sanitizer_posix.h" + #include -#include #if defined(__x86_64__) || defined(__i386__) # include #endif #if defined(__arm__) || defined(__aarch64__) -# include +// getauxval() was introduced with API level 18 on Android. +# if SANITIZER_ANDROID && __ANDROID_API__ < 18 +# define SCUDO_USE_GETAUXVAL 0 +# else +# define SCUDO_USE_GETAUXVAL 1 +# endif +# if SCUDO_USE_GETAUXVAL +# include +# else +# include +# endif #endif // TODO(kostyak): remove __sanitizer *Printf uses in favor for our own less @@ -82,9 +91,9 @@ return FeaturesRegs; } -#ifndef bit_SSE4_2 -# define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines. -#endif +# ifndef bit_SSE4_2 +# define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines. +# endif bool testCPUFeature(CPUFeature Feature) { @@ -99,15 +108,43 @@ return false; } #elif defined(__arm__) || defined(__aarch64__) -// For ARM and AArch64, hardware CRC32 support is indicated in the -// AT_HWVAL auxiliary vector. +// For ARM and AArch64, hardware CRC32 support is indicated in the AT_HWVAL +// auxiliary vector. -#ifndef HWCAP_CRC32 -# define HWCAP_CRC32 (1<<7) // HWCAP_CRC32 is missing on older platforms. -#endif +# ifndef AT_HWCAP +# define AT_HWCAP 16 +# endif +# ifndef HWCAP_CRC32 +# define HWCAP_CRC32 (1<<7) // HWCAP_CRC32 is missing on older platforms. +# endif + +# if SCUDO_USE_GETAUXVAL +uptr getHWCap() { return getauxval(AT_HWCAP); } +# else +uptr getHWCap() { + uptr F = internal_open("/proc/self/auxv", O_RDONLY); + if (internal_iserror(F)) + return 0; + struct { uptr Tag; uptr Value; } Entry; + uptr Result = 0; + for (;;) { + uptr N = internal_read(F, &Entry, sizeof(Entry)); + if (internal_iserror(N)) + break; + if (N == 0 || N != sizeof(Entry) || (Entry.Tag == 0 && Entry.Value == 0)) + break; + if (Entry.Tag == AT_HWCAP) { + Result = Entry.Value; + break; + } + } + internal_close(F); + return Result; +} +# endif // SCUDO_USE_GETAUXVAL bool testCPUFeature(CPUFeature Feature) { - uptr HWCap = getauxval(AT_HWCAP); + uptr HWCap = getHWCap(); switch (Feature) { case CRC32CPUFeature: