[compiler-rt] [asan] Intercept __makecontext_v2 on Solaris/SPARC (PR #81588)
Rainer Orth via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 13 01:28:26 PST 2024
https://github.com/rorth created https://github.com/llvm/llvm-project/pull/81588
As detailed in [GCC PR
sanitizer/113785](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113785), the GCC test `c-c++-common/asan/swapcontext-test-1.c` `FAIL`s on Solaris/sparc.
This is due to the fact that Solaris 10/SPARC changed the semantics of `makecontext` so `ucontext_t.uc_stack.ss_sp` refers to the stack base address. To maintain binary compatiblity, the external name was changed to `__makecontext_v2`, keeping the old version.
To match this, `__makecontext_v2` needs to be intercepted instead of `makecontext`.
Tested on GCC trunk on `sparc-sun-solaris2.11`, `i386-pc-solaris2.11`, and `x86_64-pc-linux-gnu`.
Also tested on the same targets on LLVM `main`. However, this only proves that Linux/x86_64 isn't broken, since all `makecontext` tests are Linux-specific.
>From ce05ff988f3d57cc936bd78f81cdd44c7d333298 Mon Sep 17 00:00:00 2001
From: Rainer Orth <ro at gcc.gnu.org>
Date: Tue, 13 Feb 2024 10:26:55 +0100
Subject: [PATCH] [asan] Intercept __makecontext_v2 on Solaris/SPARC
As detailed in [GCC PR
sanitizer/113785](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113785), the
GCC test `c-c++-common/asan/swapcontext-test-1.c` `FAIL`s on Solaris/sparc.
This is due to the fact that Solaris 10/SPARC changed the semantics of
`makecontext` so `ucontext_t.uc_stack.ss_sp` refers to the stack base
address. To maintain binary compatiblity, the external name was changed to
`__makecontext_v2`, keeping the old version.
To match this, `__makecontext_v2` needs to be intercepted instead of
`makecontext`.
Tested on GCC trunk on `sparc-sun-solaris2.11`, `i386-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.
Also tested on the same targets on LLVM `main`. However, this only proves
that Linux/x86_64 isn't broken, since all `makecontext` tests are
Linux-specific.
---
compiler-rt/lib/asan/asan_interceptors.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp
index 4de2fa356374a6..9d383b9d37c4a1 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cpp
+++ b/compiler-rt/lib/asan/asan_interceptors.cpp
@@ -352,8 +352,16 @@ static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
PoisonShadow(bottom, ssize, 0);
}
+// Since Solaris 10/SPARC, ucp->uc_stack.ss_sp refers to the stack base address
+// as on other targets. For binary compatibility, the new version uses a
+// different external name, so we intercept that.
+# if SANITIZER_SOLARIS && defined(__sparc__)
+INTERCEPTOR(void, __makecontext_v2, struct ucontext_t *ucp, void (*func)(),
+ int argc, ...) {
+# else
INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
...) {
+# endif
va_list ap;
uptr args[64];
// We don't know a better way to forward ... into REAL function. We can
@@ -373,7 +381,11 @@ INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
ENUMERATE_ARRAY_16(0), ENUMERATE_ARRAY_16(16), ENUMERATE_ARRAY_16(32), \
ENUMERATE_ARRAY_16(48)
+# if SANITIZER_SOLARIS && defined(__sparc__)
+ REAL(__makecontext_v2)
+# else
REAL(makecontext)
+# endif
((struct ucontext_t *)ucp, func, argc, ENUMERATE_ARRAY_64());
# undef ENUMERATE_ARRAY_4
@@ -780,7 +792,12 @@ void InitializeAsanInterceptors() {
# if ASAN_INTERCEPT_SWAPCONTEXT
ASAN_INTERCEPT_FUNC(swapcontext);
+ // See the makecontext interceptor above for an explanation.
+# if SANITIZER_SOLARIS && defined(__sparc__)
+ ASAN_INTERCEPT_FUNC(__makecontext_v2);
+# else
ASAN_INTERCEPT_FUNC(makecontext);
+# endif
# endif
# if ASAN_INTERCEPT__LONGJMP
ASAN_INTERCEPT_FUNC(_longjmp);
More information about the llvm-commits
mailing list