diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2017-09-06 17:51:32 +0000 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2017-09-06 17:51:32 +0000 |
commit | 35e74d5f69b8936980b9d9f07f4bc15be21a0bcc (patch) | |
tree | 1383691d2e9ebe4b5577060730b7cc195f66fa05 | |
parent | 3bf34db38678fbb8dbb508e171c3ce1aa9d96c04 (diff) |
[scudo] getauxval alternative for Android
Summary:
`getauxval` was introduced with API level 18. In order to get things to work
at lower API levels (for the toolchain itself which is built at 14 for 32-bit),
we introduce an alternative implementation reading directly from
`/proc/self/auxv`.
Reviewers: alekseyshl
Reviewed By: alekseyshl
Subscribers: srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D37488
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@312653 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/scudo/scudo_utils.cpp | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/lib/scudo/scudo_utils.cpp b/lib/scudo/scudo_utils.cpp index f7903ff34..71d1b2e1b 100644 --- a/lib/scudo/scudo_utils.cpp +++ b/lib/scudo/scudo_utils.cpp @@ -13,15 +13,47 @@ #include "scudo_utils.h" -#include <errno.h> -#include <fcntl.h> +#include "sanitizer_common/sanitizer_posix.h" + #include <stdarg.h> -#include <unistd.h> #if defined(__x86_64__) || defined(__i386__) # include <cpuid.h> #endif #if defined(__arm__) || defined(__aarch64__) -# include <sys/auxv.h> +# if SANITIZER_ANDROID && __ANDROID_API__ < 18 +// getauxval() was introduced with API level 18 on Android. Emulate it using +// /proc/self/auxv for lower API levels. +# include <fcntl.h> + +# define AT_HWCAP 16 + +namespace __sanitizer { + +uptr getauxval(uptr Type) { + 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 == Type) { + Result = Entry.Value; + break; + } + } + internal_close(F); + return Result; +} + +} // namespace __sanitizer +# else +# include <sys/auxv.h> +# endif #endif // TODO(kostyak): remove __sanitizer *Printf uses in favor for our own less @@ -82,9 +114,9 @@ CPUIDRegs getCPUFeatures() { 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,12 +131,12 @@ bool testCPUFeature(CPUFeature Feature) 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 HWCAP_CRC32 +# define HWCAP_CRC32 (1 << 7) // HWCAP_CRC32 is missing on older platforms. +# endif bool testCPUFeature(CPUFeature Feature) { uptr HWCap = getauxval(AT_HWCAP); |