Skip to content

Commit 8c20337

Browse files
authored
[asan] Intercept __makecontext_v2 on Solaris/SPARC (#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.
1 parent 3b6e250 commit 8c20337

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

compiler-rt/lib/asan/asan_interceptors.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,16 @@ static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
352352
PoisonShadow(bottom, ssize, 0);
353353
}
354354

355+
// Since Solaris 10/SPARC, ucp->uc_stack.ss_sp refers to the stack base address
356+
// as on other targets. For binary compatibility, the new version uses a
357+
// different external name, so we intercept that.
358+
# if SANITIZER_SOLARIS && defined(__sparc__)
359+
INTERCEPTOR(void, __makecontext_v2, struct ucontext_t *ucp, void (*func)(),
360+
int argc, ...) {
361+
# else
355362
INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
356363
...) {
364+
# endif
357365
va_list ap;
358366
uptr args[64];
359367
// 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,
373381
ENUMERATE_ARRAY_16(0), ENUMERATE_ARRAY_16(16), ENUMERATE_ARRAY_16(32), \
374382
ENUMERATE_ARRAY_16(48)
375383

384+
# if SANITIZER_SOLARIS && defined(__sparc__)
385+
REAL(__makecontext_v2)
386+
# else
376387
REAL(makecontext)
388+
# endif
377389
((struct ucontext_t *)ucp, func, argc, ENUMERATE_ARRAY_64());
378390

379391
# undef ENUMERATE_ARRAY_4
@@ -780,7 +792,12 @@ void InitializeAsanInterceptors() {
780792

781793
# if ASAN_INTERCEPT_SWAPCONTEXT
782794
ASAN_INTERCEPT_FUNC(swapcontext);
795+
// See the makecontext interceptor above for an explanation.
796+
# if SANITIZER_SOLARIS && defined(__sparc__)
797+
ASAN_INTERCEPT_FUNC(__makecontext_v2);
798+
# else
783799
ASAN_INTERCEPT_FUNC(makecontext);
800+
# endif
784801
# endif
785802
# if ASAN_INTERCEPT__LONGJMP
786803
ASAN_INTERCEPT_FUNC(_longjmp);

0 commit comments

Comments
 (0)