summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2017-09-06 17:51:32 +0000
committerKostya Kortchinsky <kostyak@google.com>2017-09-06 17:51:32 +0000
commit35e74d5f69b8936980b9d9f07f4bc15be21a0bcc (patch)
tree1383691d2e9ebe4b5577060730b7cc195f66fa05
parent3bf34db38678fbb8dbb508e171c3ce1aa9d96c04 (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.cpp56
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);