[PATCH] D37488: [scudo] getauxval alternative for Android

Kostya Kortchinsky via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 5 12:27:40 PDT 2017


cryptoad created this revision.
Herald added a subscriber: srhines.

`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`.


https://reviews.llvm.org/D37488

Files:
  lib/scudo/scudo_utils.cpp


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 <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>
+// 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 <sys/auxv.h>
+# else
+#  include <fcntl.h>
+# 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:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37488.113893.patch
Type: text/x-patch
Size: 2506 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170905/9f6b8fdb/attachment.bin>


More information about the llvm-commits mailing list