Index: lib/tsan/rtl/tsan_interceptors.cc =================================================================== --- lib/tsan/rtl/tsan_interceptors.cc +++ lib/tsan/rtl/tsan_interceptors.cc @@ -502,15 +502,17 @@ static void LongJmp(ThreadState *thr, uptr *env) { #ifdef __powerpc__ uptr mangled_sp = env[0]; -#elif SANITIZER_FREEBSD || SANITIZER_NETBSD +#elif SANITIZER_FREEBSD uptr mangled_sp = env[2]; +#elif SANITIZER_NETBSD + uptr mangled_sp = env[6]; #elif SANITIZER_MAC # ifdef __aarch64__ uptr mangled_sp = env[13]; # else uptr mangled_sp = env[2]; # endif -#elif defined(SANITIZER_LINUX) +#elif SANITIZER_LINUX # ifdef __aarch64__ uptr mangled_sp = env[13]; # elif defined(__mips64) @@ -548,7 +550,37 @@ SetJmp(cur_thread(), sp, mangled_sp); } -#if SANITIZER_MAC +#if SANITIZER_NETBSD +// Not called. Merely to satisfy TSAN_INTERCEPT(). +extern "C" SANITIZER_INTERFACE_ATTRIBUTE +int __interceptor___setjmp14(void *env); +extern "C" int __interceptor___setjmp14(void *env) { + CHECK(0); + return 0; +} + +// FIXME: any reason to have a separate declaration? +extern "C" SANITIZER_INTERFACE_ATTRIBUTE +int __interceptor___sigsetjmp14(void *env, int val); +extern "C" int __interceptor___sigsetjmp14(void *env, int val) { + CHECK(0); + return 0; +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE +int __interceptor_setjmp(void *env); +extern "C" int __interceptor_setjmp(void *env) { + CHECK(0); + return 0; +} + +extern "C" int __setjmp14(void *env); +extern "C" int __sigsetjmp14(void *env, int val); +extern "C" int _setjmp(void *env); +DEFINE_REAL(int, __setjmp14, void *env) +DEFINE_REAL(int, __sigsetjmp14, void *env, int val) +DEFINE_REAL(int, _setjmp, void *env) +#elif SANITIZER_MAC TSAN_INTERCEPTOR(int, setjmp, void *env); TSAN_INTERCEPTOR(int, _setjmp, void *env); TSAN_INTERCEPTOR(int, sigsetjmp, void *env); @@ -593,6 +625,37 @@ DEFINE_REAL(int, __sigsetjmp, void *env) #endif // SANITIZER_MAC +#if SANITIZER_NETBSD +TSAN_INTERCEPTOR(void, __longjmp14, uptr *env, int val) { + // Note: if we call REAL(longjmp) in the context of ScopedInterceptor, + // bad things will happen. We will jump over ScopedInterceptor dtor and can + // leave thr->in_ignored_lib set. + { + SCOPED_INTERCEPTOR_RAW(__longjmp14, env, val); + } + LongJmp(cur_thread(), env); + REAL(__longjmp14)(env, val); +} + +TSAN_INTERCEPTOR(void, __siglongjmp14, uptr *env, int val) { + { + SCOPED_INTERCEPTOR_RAW(__siglongjmp14, env, val); + } + LongJmp(cur_thread(), env); + REAL(__siglongjmp14)(env, val); +} + +TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) { + // Note: if we call REAL(longjmp) in the context of ScopedInterceptor, + // bad things will happen. We will jump over ScopedInterceptor dtor and can + // leave thr->in_ignored_lib set. + { + SCOPED_INTERCEPTOR_RAW(_longjmp, env, val); + } + LongJmp(cur_thread(), env); + REAL(_longjmp)(env, val); +} +#else TSAN_INTERCEPTOR(void, longjmp, uptr *env, int val) { // Note: if we call REAL(longjmp) in the context of ScopedInterceptor, // bad things will happen. We will jump over ScopedInterceptor dtor and can @@ -611,6 +674,7 @@ LongJmp(cur_thread(), env); REAL(siglongjmp)(env, val); } +#endif #if !SANITIZER_MAC TSAN_INTERCEPTOR(void*, malloc, uptr size) { @@ -2545,6 +2609,16 @@ InitializeCommonInterceptors(); InitializeSignalInterceptors(); +#if SANITIZER_NETBSD + using __interception::GetRealFunctionAddress; + GetRealFunctionAddress("__setjmp14", (uptr*)&REAL(__setjmp14), 0, 0); + GetRealFunctionAddress("__sigsetjmp14", (uptr*)&REAL(__sigsetjmp14), 0, 0); + GetRealFunctionAddress("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); + + TSAN_INTERCEPT(__longjmp14); + TSAN_INTERCEPT(__siglongjmp14); + TSAN_INTERCEPT(_longjmp); +#else #if !SANITIZER_MAC // We can not use TSAN_INTERCEPT to get setjmp addr, // because it does &setjmp and setjmp is not present in some versions of libc. @@ -2557,6 +2631,7 @@ TSAN_INTERCEPT(longjmp); TSAN_INTERCEPT(siglongjmp); +#endif TSAN_INTERCEPT(malloc); TSAN_INTERCEPT(__libc_memalign); Index: lib/tsan/rtl/tsan_rtl_amd64.S =================================================================== --- lib/tsan/rtl/tsan_rtl_amd64.S +++ lib/tsan/rtl/tsan_rtl_amd64.S @@ -170,19 +170,27 @@ CFI_ENDPROC ASM_HIDDEN(__tsan_setjmp) -#if !defined(__APPLE__) +#if defined(__NetBSD__) +.comm _ZN14__interception15real___setjmp14E,8,8 +#elif !defined(__APPLE__) .comm _ZN14__interception11real_setjmpE,8,8 #endif +#if defined(__NetBSD__) +.globl ASM_TSAN_SYMBOL_INTERCEPTOR(__setjmp14) +ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__setjmp14)) +ASM_TSAN_SYMBOL_INTERCEPTOR(__setjmp14): +#else .globl ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp) ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)) ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp): +#endif CFI_STARTPROC // save env parameter push %rdi CFI_ADJUST_CFA_OFFSET(8) CFI_REL_OFFSET(%rdi, 0) // obtain %rsp -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) lea 8(%rsp), %rdi mov %rdi, %rsi #elif defined(__APPLE__) @@ -204,14 +212,21 @@ CFI_RESTORE(%rdi) // tail jump to libc setjmp movl $0, %eax -#if !defined(__APPLE__) +#if defined(__NetBSD__) + movq _ZN14__interception15real___setjmp14E@GOTPCREL(%rip), %rdx + jmp *(%rdx) +#elif !defined(__APPLE__) movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) #else jmp ASM_TSAN_SYMBOL(setjmp) #endif CFI_ENDPROC +#if defined(__NetBSD__) +ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__setjmp14)) +#else ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)) +#endif .comm _ZN14__interception12real__setjmpE,8,8 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp) @@ -223,7 +238,7 @@ CFI_ADJUST_CFA_OFFSET(8) CFI_REL_OFFSET(%rdi, 0) // obtain %rsp -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) lea 8(%rsp), %rdi mov %rdi, %rsi #elif defined(__APPLE__) @@ -254,10 +269,17 @@ CFI_ENDPROC ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)) +#if defined(__NetBSD__) +.comm _ZN14__interception18real___sigsetjmp14E,8,8 +.globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp14) +ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp14)) +ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp14): +#else .comm _ZN14__interception14real_sigsetjmpE,8,8 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp) ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)) ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): +#endif CFI_STARTPROC // save env parameter push %rdi @@ -271,7 +293,7 @@ sub $8, %rsp CFI_ADJUST_CFA_OFFSET(8) // obtain %rsp -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) lea 24(%rsp), %rdi mov %rdi, %rsi #elif defined(__APPLE__) @@ -300,16 +322,23 @@ CFI_RESTORE(%rdi) // tail jump to libc sigsetjmp movl $0, %eax -#if !defined(__APPLE__) +#if defined(__NetBSD__) + movq _ZN14__interception18real___sigsetjmp14E@GOTPCREL(%rip), %rdx + jmp *(%rdx) +#elif !defined(__APPLE__) movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) #else jmp ASM_TSAN_SYMBOL(sigsetjmp) #endif CFI_ENDPROC +#if defined(__NetBSD__) +ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp14)) +#else ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)) +#endif -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(__NetBSD__) .comm _ZN14__interception16real___sigsetjmpE,8,8 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp) ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)) @@ -355,10 +384,11 @@ jmp *(%rdx) CFI_ENDPROC ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)) -#endif // !defined(__APPLE__) +#endif // !defined(__APPLE__) && !defined(__NetBSD__) #if defined(__FreeBSD__) || defined(__linux__) /* We do not need executable stack. */ +/* This note is not needed on NetBSD. */ .section .note.GNU-stack,"",@progbits #endif