diff mbox series

libsanitizer: Intercept __makecontext_v2 on Solaris/SPARC [PR113785]

Message ID ydda5o0zj23.fsf@CeBiTec.Uni-Bielefeld.DE
State New
Headers show
Series libsanitizer: Intercept __makecontext_v2 on Solaris/SPARC [PR113785] | expand

Commit Message

Rainer Orth Feb. 16, 2024, 12:32 p.m. UTC
c-c++-common/asan/swapcontext-test-1.c FAILs on Solaris/SPARC:

FAIL: c-c++-common/asan/swapcontext-test-1.c   -O0  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O1  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2 -flto  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2 -flto -flto-partition=none  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O3 -g  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -Os  execution test

As detailed in PR sanitizer/113785, this happens because an ABI change
in Solaris 10/SPARC caused the external symbol for makecontext to be
changed to __makecontext_v2, which isn't intercepted.

The following patch, submitted upstream at
https://github.com/llvm/llvm-project/pull/81588, fixes that.

Tested on sparc-sun-solaris2.11 and i386-pc-solaris2.11.

Ok to cherry-pick into trunk?

	Rainer

Comments

Jakub Jelinek Feb. 16, 2024, 12:54 p.m. UTC | #1
On Fri, Feb 16, 2024 at 01:32:04PM +0100, Rainer Orth wrote:
> c-c++-common/asan/swapcontext-test-1.c FAILs on Solaris/SPARC:
> 
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O0  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O1  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2 -flto  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2 -flto -flto-partition=none  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O3 -g  execution test
> FAIL: c-c++-common/asan/swapcontext-test-1.c   -Os  execution test
> 
> As detailed in PR sanitizer/113785, this happens because an ABI change
> in Solaris 10/SPARC caused the external symbol for makecontext to be
> changed to __makecontext_v2, which isn't intercepted.

Is Solaris 9/SPARC and earlier no longer supported in GCC?

If so, ok for trunk.

Otherwise I'd expect some ifdefs or whatever to check if it is
Solaris 10+ with __makecontext_v2 or Solaris up to 9 with makecontext.

	Jakub
Rainer Orth Feb. 16, 2024, 1 p.m. UTC | #2
Hi Jakub,

> On Fri, Feb 16, 2024 at 01:32:04PM +0100, Rainer Orth wrote:
>> c-c++-common/asan/swapcontext-test-1.c FAILs on Solaris/SPARC:
>> 
>> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O0  execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O1  execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2  execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2 -flto  execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c -O2 -flto
>> -flto-partition=none execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c -O3 -fomit-frame-pointer
>> -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c   -O3 -g  execution test
>> FAIL: c-c++-common/asan/swapcontext-test-1.c   -Os  execution test
>> 
>> As detailed in PR sanitizer/113785, this happens because an ABI change
>> in Solaris 10/SPARC caused the external symbol for makecontext to be
>> changed to __makecontext_v2, which isn't intercepted.
>
> Is Solaris 9/SPARC and earlier no longer supported in GCC?

no, Solaris 9 support was removed in GCC 5 already.  The only version
supported by trunk is 11.4; 11.3 isn't but I won't actually remove
support until Solaris 11.4 systems have been added to the cfarm (which
should be soon).

> If so, ok for trunk.

Thanks.

> Otherwise I'd expect some ifdefs or whatever to check if it is
> Solaris 10+ with __makecontext_v2 or Solaris up to 9 with makecontext.

True.  However, it can be difficult to get patches upstream for OS
versions not remotely supported in LLVM (which has been 11.4-only for
years).

	Rainer
diff mbox series

Patch

# HG changeset patch
# Parent  2fb800df7e0fd2d03a485601ad4683a29f78f2a4
libsanitizer: Intercept __makecontext_v2 on Solaris/SPARC [PR113785]

diff --git a/libsanitizer/asan/asan_interceptors.cpp b/libsanitizer/asan/asan_interceptors.cpp
--- a/libsanitizer/asan/asan_interceptors.cpp
+++ b/libsanitizer/asan/asan_interceptors.cpp
@@ -347,8 +347,16 @@  static void ClearShadowMemoryForContextS
   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
@@ -368,7 +376,11 @@  INTERCEPTOR(void, makecontext, struct uc
       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
@@ -783,7 +795,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);