[compiler-rt] r236628 - [asan] Fall back to /proc/$PID/maps on Android L.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Wed May 6 11:55:31 PDT 2015
Author: eugenis
Date: Wed May 6 13:55:31 2015
New Revision: 236628
URL: http://llvm.org/viewvc/llvm-project?rev=236628&view=rev
Log:
[asan] Fall back to /proc/$PID/maps on Android L.
dl_iterate_phdr is somewhat broken in L (see the code for details).
We add runtime OS version detection and fallback to /proc/maps on L or earlier.
This fixes a number of ASan tests on L.
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=236628&r1=236627&r2=236628&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed May 6 13:55:31 2015
@@ -622,11 +622,13 @@ void AndroidLogInit();
void AndroidLogWrite(const char *buffer);
void GetExtraActivationFlags(char *buf, uptr size);
void SanitizerInitializeUnwinder();
+u32 AndroidGetApiLevel();
#else
INLINE void AndroidLogInit() {}
INLINE void AndroidLogWrite(const char *buffer_unused) {}
INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; }
INLINE void SanitizerInitializeUnwinder() {}
+INLINE u32 AndroidGetApiLevel() { return 0; }
#endif
void *internal_start_thread(void(*func)(void*), void *arg);
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=236628&r1=236627&r2=236628&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Wed May 6 13:55:31 2015
@@ -46,9 +46,7 @@
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
-#if !SANITIZER_ANDROID
#include <link.h>
-#endif
#include <pthread.h>
#include <sched.h>
#include <sys/mman.h>
@@ -964,6 +962,46 @@ void GetExtraActivationFlags(char *buf,
CHECK(size > PROP_VALUE_MAX);
__system_property_get("asan.options", buf);
}
+
+#if __ANDROID_API__ < 21
+extern "C" __attribute__((weak)) int dl_iterate_phdr(
+ int (*)(struct dl_phdr_info *, size_t, void *), void *);
+#endif
+
+static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
+ void *data) {
+ // Any name starting with "lib" indicated a bug in L where library base names
+ // are returned instead of paths.
+ if (info->dlpi_name && info->dlpi_name[0] == 'l' &&
+ info->dlpi_name[1] == 'i' && info->dlpi_name[2] == 'b') {
+ *(bool *)data = true;
+ return 1;
+ }
+ return 0;
+}
+
+static atomic_uint32_t android_api_level;
+
+static u32 AndroidDetectApiLevel() {
+ if (!dl_iterate_phdr)
+ return 19; // K or lower
+ bool base_name_seen = false;
+ dl_iterate_phdr(dl_iterate_phdr_test_cb, &base_name_seen);
+ if (base_name_seen)
+ return 22; // L MR1
+ return 23; // post-L
+ // Plain L (API level 21) is completely broken wrt ASan and not very
+ // interesting to detect.
+}
+
+u32 AndroidGetApiLevel() {
+ u32 level = atomic_load(&android_api_level, memory_order_relaxed);
+ if (level) return level;
+ level = AndroidDetectApiLevel();
+ atomic_store(&android_api_level, level, memory_order_relaxed);
+ return level;
+}
+
#endif
bool IsDeadlySignal(int signum) {
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc?rev=236628&r1=236627&r2=236628&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc Wed May 6 13:55:31 2015
@@ -456,10 +456,11 @@ extern "C" __attribute__((weak)) int dl_
uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
string_predicate_t filter) {
#if SANITIZER_ANDROID && __ANDROID_API__ < 21
- // Fall back to /proc/maps if dl_iterate_phdr is not available.
+ u32 api_level = AndroidGetApiLevel();
+ // Fall back to /proc/maps if dl_iterate_phdr is unavailable or broken.
// The runtime check allows the same library to work with
// both K and L (and future) Android releases.
- if (!dl_iterate_phdr) {
+ if (api_level <= 22) { // L or earlier
MemoryMappingLayout memory_mapping(false);
return memory_mapping.DumpListOfModules(modules, max_modules, filter);
}
More information about the llvm-commits
mailing list