[compiler-rt] 484ec6b - Reland [lsan] Enable LSAN for Android
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 4 18:00:41 PST 2020
Author: Vy Nguyen
Date: 2020-11-04T18:00:25-08:00
New Revision: 484ec6be30663f980db233fee6c197493b0fe0d7
URL: https://github.com/llvm/llvm-project/commit/484ec6be30663f980db233fee6c197493b0fe0d7
DIFF: https://github.com/llvm/llvm-project/commit/484ec6be30663f980db233fee6c197493b0fe0d7.diff
LOG: Reland [lsan] Enable LSAN for Android
Reland: a2291a58bf1c860d026581fee6fe96019dc25440.
New fixes for the breakages reported in D85927 include:
- declare a weak decl for `dl_iterate_phdr`, because it does not exist on older APIs
- Do not enable leak-sanitizer if api_level is less than 29, because of `ld.lld: error: undefined symbol: __aeabi_read_tp` for armv7, API level 16.
- Put back the interceptor for `memalign` but still opt out intercepting `__libc_memalign` and `cfree` because both of these don't exist in Bionic.
Reviewed By: srhines, vitalybuka
Differential Revision: https://reviews.llvm.org/D89251
Added:
Modified:
compiler-rt/cmake/config-ix.cmake
compiler-rt/lib/asan/tests/CMakeLists.txt
compiler-rt/lib/lsan/lsan_common.cpp
compiler-rt/lib/lsan/lsan_common.h
compiler-rt/lib/lsan/lsan_common_linux.cpp
compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
compiler-rt/lib/sanitizer_common/sanitizer_linux.h
compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Removed:
################################################################################
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 88f855d19543..d13e75e41685 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -687,7 +687,7 @@ else()
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND
- OS_NAME MATCHES "Darwin|Linux|NetBSD|Fuchsia")
+ OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|Fuchsia")
set(COMPILER_RT_HAS_LSAN TRUE)
else()
set(COMPILER_RT_HAS_LSAN FALSE)
diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt
index cb30663b10b5..e56ae16288ca 100644
--- a/compiler-rt/lib/asan/tests/CMakeLists.txt
+++ b/compiler-rt/lib/asan/tests/CMakeLists.txt
@@ -286,6 +286,7 @@ if(ANDROID)
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
+ $<TARGET_OBJECTS:RTLSanCommon.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
${COMPILER_RT_GTEST_SOURCE}
diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index fa16f78c1c2b..7b759d420808 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -294,6 +294,20 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
kReachable);
}
}
+#if SANITIZER_ANDROID
+ auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/,
+ void *arg) -> void {
+ ScanRangeForPointers(reinterpret_cast<uptr>(dtls_begin),
+ reinterpret_cast<uptr>(dtls_end),
+ reinterpret_cast<Frontier *>(arg), "DTLS",
+ kReachable);
+ };
+
+ // FIXME: There might be a race-condition here (and in Bionic) if the
+ // thread is suspended in the middle of updating its DTLS. IOWs, we
+ // could scan already freed memory. (probably fine for now)
+ __libc_iterate_dynamic_tls(os_id, cb, frontier);
+#else
if (dtls && !DTLSInDestruction(dtls)) {
for (uptr j = 0; j < dtls->dtv_size; ++j) {
uptr dtls_beg = dtls->dtv[j].beg;
@@ -309,6 +323,7 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
// this and continue.
LOG_THREADS("Thread %d has DTLS under destruction.\n", os_id);
}
+#endif
}
}
}
diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index 7bb4b06aace4..53d7fad57e0d 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -29,13 +29,17 @@
// To enable LeakSanitizer on a new architecture, one needs to implement the
// internal_clone function as well as (probably) adjust the TLS machinery for
// the new architecture inside the sanitizer library.
-#if (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC) && \
+#if (SANITIZER_LINUX && \
+ (!SANITIZER_ANDROID || defined(ANDROID_HAS_ELF_TLS)) || \
+ SANITIZER_MAC) && \
(SANITIZER_WORDSIZE == 64) && \
(defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \
defined(__powerpc64__) || defined(__s390x__))
#define CAN_SANITIZE_LEAKS 1
-#elif defined(__i386__) && \
- (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC)
+#elif defined(__i386__) && \
+ (SANITIZER_LINUX && \
+ (!SANITIZER_ANDROID || defined(ANDROID_HAS_ELF_TLS)) || \
+ SANITIZER_MAC)
#define CAN_SANITIZE_LEAKS 1
#elif defined(__arm__) && SANITIZER_LINUX && !SANITIZER_ANDROID
#define CAN_SANITIZE_LEAKS 1
diff --git a/compiler-rt/lib/lsan/lsan_common_linux.cpp b/compiler-rt/lib/lsan/lsan_common_linux.cpp
index c97ef31593df..3af586e220f6 100644
--- a/compiler-rt/lib/lsan/lsan_common_linux.cpp
+++ b/compiler-rt/lib/lsan/lsan_common_linux.cpp
@@ -93,6 +93,11 @@ static int ProcessGlobalRegionsCallback(struct dl_phdr_info *info, size_t size,
return 0;
}
+#if SANITIZER_ANDROID && __ANDROID_API__ < 21
+extern "C" __attribute__((weak)) int dl_iterate_phdr(
+ int (*)(struct dl_phdr_info *, size_t, void *), void *);
+#endif
+
// Scans global variables for heap pointers.
void ProcessGlobalRegions(Frontier *frontier) {
if (!flags()->use_globals) return;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
index cc898398eaf2..ecfe24dd66d4 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.cpp
@@ -13,9 +13,10 @@
#include "sanitizer_flags.h"
#include "sanitizer_common.h"
+#include "sanitizer_flag_parser.h"
#include "sanitizer_libc.h"
+#include "sanitizer_linux.h"
#include "sanitizer_list.h"
-#include "sanitizer_flag_parser.h"
namespace __sanitizer {
@@ -124,6 +125,9 @@ void InitializeCommonFlags(CommonFlags *cf) {
// need to record coverage to generate coverage report.
cf->coverage |= cf->html_cov_report;
SetVerbosity(cf->verbosity);
+
+ if (SANITIZER_ANDROID && !HAS_ANDROID_THREAD_PROPERTIES_API)
+ cf->detect_leaks = false;
}
} // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 24902d1b6bce..954215662494 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -153,6 +153,16 @@ ALWAYS_INLINE uptr *get_android_tls_ptr() {
return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]);
}
+// Bionic provides this API since S.
+extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_get_static_tls_bounds(void **,
+ void **);
+extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_iterate_dynamic_tls(
+ pid_t, void (*cb)(void *, void *, uptr, void *), void *);
+
+#define HAS_ANDROID_THREAD_PROPERTIES_API (&__libc_iterate_dynamic_tls != 0)
+
+#else
+#define HAS_ANDROID_THREAD_PROPERTIES_API (0)
#endif // SANITIZER_ANDROID
} // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index 10627549704a..20d18f854e42 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -447,7 +447,19 @@ int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) {
#if !SANITIZER_GO
static void GetTls(uptr *addr, uptr *size) {
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if SANITIZER_ANDROID
+ if (HAS_ANDROID_THREAD_PROPERTIES_API) {
+ void *start_addr;
+ void *end_addr;
+ __libc_get_static_tls_bounds(&start_addr, &end_addr);
+ *addr = reinterpret_cast<uptr>(start_addr);
+ *size =
+ reinterpret_cast<uptr>(end_addr) - reinterpret_cast<uptr>(start_addr);
+ } else {
+ *addr = 0;
+ *size = 0;
+ }
+#elif SANITIZER_LINUX
#if defined(__x86_64__) || defined(__i386__) || defined(__s390__)
*addr = ThreadSelf();
*size = GetTlsSize();
@@ -488,9 +500,6 @@ static void GetTls(uptr *addr, uptr *size) {
*addr = (uptr)tcb->tcb_dtv[1];
}
}
-#elif SANITIZER_ANDROID
- *addr = 0;
- *size = 0;
#elif SANITIZER_SOLARIS
// FIXME
*addr = 0;
More information about the llvm-commits
mailing list