-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[TSan] Add support for Android #147580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[TSan] Add support for Android #147580
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Peng Fei (airpfei) ChangesThis PR fixs some bugs to enable TSan support on Android. It will resolve the issue from NDK android/ndk#1041. Full diff: https://github.com/llvm/llvm-project/pull/147580.diff 6 Files Affected:
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 2d6cf7fc3282f..6ad7c854f8d50 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1287,6 +1287,14 @@ INTERCEPTOR(int, puts, char *s) {
#if SANITIZER_INTERCEPT_PRCTL
INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5) {
+# if SANITIZER_ANDROID
+ static const int PR_PAC_RESET_KEYS = 54;
+ // workaround to avoid crash
+ if (option == PR_PAC_RESET_KEYS) {
+ return REAL(prctl)(option, arg2, arg3, arg4, arg5);
+ }
+# endif
+
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
static const int PR_SET_NAME = 15;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
index 351e00db6fb2d..855c9923292c5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp
@@ -89,7 +89,7 @@ static inline bool ReportSupportsColors() { return true; }
bool ColorizeReports() {
// FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color
// printing on Windows.
- if (SANITIZER_WINDOWS)
+ if (SANITIZER_WINDOWS || SANITIZER_ANDROID)
return false;
const char *flag = common_flags()->color;
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 14b25a8995dab..fdbfc0c4e5220 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -2411,7 +2411,7 @@ TSAN_INTERCEPTOR(int, vfork, int fake) {
}
#endif
-#if SANITIZER_LINUX
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
TSAN_INTERCEPTOR(int, clone, int (*fn)(void *), void *stack, int flags,
void *arg, int *parent_tid, void *tls, pid_t *child_tid) {
SCOPED_INTERCEPTOR_RAW(clone, fn, stack, flags, arg, parent_tid, tls,
@@ -3120,7 +3120,7 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(fork);
TSAN_INTERCEPT(vfork);
-#if SANITIZER_LINUX
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
TSAN_INTERCEPT(clone);
#endif
#if !SANITIZER_ANDROID
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
index 2c55645a15479..cd48eadfa7af9 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -66,15 +66,16 @@ extern "C" void *__libc_stack_end;
void *__libc_stack_end = 0;
#endif
-#if SANITIZER_LINUX && (defined(__aarch64__) || defined(__loongarch_lp64)) && \
- !SANITIZER_GO
-# define INIT_LONGJMP_XOR_KEY 1
-#else
-# define INIT_LONGJMP_XOR_KEY 0
-#endif
+# if SANITIZER_LINUX && \
+ (defined(__aarch64__) || defined(__loongarch_lp64)) && !SANITIZER_GO && \
+ !SANITIZER_ANDROID
+# define INIT_LONGJMP_XOR_KEY 1
+# else
+# define INIT_LONGJMP_XOR_KEY 0
+# endif
-#if INIT_LONGJMP_XOR_KEY
-#include "interception/interception.h"
+# if INIT_LONGJMP_XOR_KEY
+# include "interception/interception.h"
// Must be declared outside of other namespaces.
DECLARE_REAL(int, _setjmp, void *env)
#endif
@@ -415,7 +416,7 @@ void InitializePlatform() {
// is not compiled with -pie.
#if !SANITIZER_GO
{
-# if SANITIZER_LINUX && (defined(__aarch64__) || defined(__loongarch_lp64))
+# if INIT_LONGJMP_XOR_KEY
// Initialize the xor key used in {sig}{set,long}jump.
InitializeLongjmpXorKey();
# endif
@@ -484,6 +485,7 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {
return res;
}
+# if !SANITIZER_ANDROID
// Reverse operation of libc stack pointer mangling
static uptr UnmangleLongJmpSp(uptr mangled_sp) {
#if defined(__x86_64__)
@@ -527,28 +529,29 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
# error "Unknown platform"
# endif
}
+# endif // !SANITIZER_ANDROID
-#if SANITIZER_NETBSD
-# ifdef __x86_64__
-# define LONG_JMP_SP_ENV_SLOT 6
-# else
-# error unsupported
-# endif
-#elif defined(__powerpc__)
-# define LONG_JMP_SP_ENV_SLOT 0
-#elif SANITIZER_FREEBSD
-# ifdef __aarch64__
-# define LONG_JMP_SP_ENV_SLOT 1
-# else
-# define LONG_JMP_SP_ENV_SLOT 2
-# endif
-#elif SANITIZER_LINUX
-# ifdef __aarch64__
-# define LONG_JMP_SP_ENV_SLOT 13
-# elif defined(__loongarch__)
-# define LONG_JMP_SP_ENV_SLOT 1
-# elif defined(__mips64)
-# define LONG_JMP_SP_ENV_SLOT 1
+# if SANITIZER_NETBSD
+# ifdef __x86_64__
+# define LONG_JMP_SP_ENV_SLOT 6
+# else
+# error unsupported
+# endif
+# elif defined(__powerpc__)
+# define LONG_JMP_SP_ENV_SLOT 0
+# elif SANITIZER_FREEBSD
+# ifdef __aarch64__
+# define LONG_JMP_SP_ENV_SLOT 1
+# else
+# define LONG_JMP_SP_ENV_SLOT 2
+# endif
+# elif SANITIZER_LINUX && !SANITIZER_ANDROID
+# ifdef __aarch64__
+# define LONG_JMP_SP_ENV_SLOT 13
+# elif defined(__loongarch__)
+# define LONG_JMP_SP_ENV_SLOT 1
+# elif defined(__mips64)
+# define LONG_JMP_SP_ENV_SLOT 1
# elif SANITIZER_RISCV64
# define LONG_JMP_SP_ENV_SLOT 13
# elif defined(__s390x__)
@@ -556,11 +559,24 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
# else
# define LONG_JMP_SP_ENV_SLOT 6
# endif
-#endif
+# elif SANITIZER_ANDROID
+# ifdef __aarch64__
+# define LONG_JMP_SP_ENV_SLOT 3
+# define LONG_JMP_COOKIE_ENV_SLOT 0
+# else
+# error unsupported
+# endif
+# endif
uptr ExtractLongJmpSp(uptr *env) {
uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
+# if SANITIZER_ANDROID
+ // This only works for Android arm64
+ // https://android.googlesource.com/platform/bionic/+/refs/heads/android16-release/libc/arch-arm64/bionic/setjmp.S#46
+ return mangled_sp ^ (env[LONG_JMP_COOKIE_ENV_SLOT] & ~1ULL);
+# else
return UnmangleLongJmpSp(mangled_sp);
+# endif
}
#if INIT_LONGJMP_XOR_KEY
@@ -653,6 +669,14 @@ ThreadState *cur_thread() {
}
CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, &oldset, nullptr));
}
+
+ // This is a temporary workaround.
+ // Somewhere wrote get_android_tls_ptr unexpected.
+ uptr addr = reinterpret_cast<uptr>(thr);
+ if (addr % 2 != 0) {
+ return reinterpret_cast<ThreadState *>(addr & ~1ULL);
+ }
+
return thr;
}
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index 0d7247a56a4c2..dec85d71d9ba3 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -662,7 +662,7 @@ void MapShadow(uptr addr, uptr size) {
addr + size, meta_begin, meta_end);
}
-#if !SANITIZER_GO
+#if !SANITIZER_GO && !SANITIZER_ANDROID
static void OnStackUnwind(const SignalContext &sig, const void *,
BufferedStackTrace *stack) {
stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
@@ -733,6 +733,9 @@ void Initialize(ThreadState *thr) {
#if !SANITIZER_GO
InitializeShadowMemory();
InitializeAllocatorLate();
+#endif
+
+#if !SANITIZER_GO && !SANITIZER_ANDROID
InstallDeadlySignalHandlers(TsanOnDeadlySignal);
#endif
// Setup correct file descriptor for error reports.
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
index 8d29e25a6dd20..5283cc595569b 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
@@ -188,7 +188,7 @@ void ThreadStart(ThreadState *thr, Tid tid, tid_t os_id,
}
#endif
-#if !SANITIZER_GO
+#if !SANITIZER_GO && !SANITIZER_ANDROID
// Don't imitate stack/TLS writes for the main thread,
// because its initialization is synchronized with all
// subsequent threads anyway.
|
This PR fixes some bugs to enable TSan support on Android.
It will resolve the issue from NDK android/ndk#1041.