[tsan] Port tsan_rtl_amd64.S to OS X to add support for setjmp/longjmp
This patch ports the assembly file tsan_rtl_amd64.S to OS X, where we need several changes: * Some assembler directives are not available on OS X (.hidden, .type, .size) * Symbol names need to start with an underscore (added a ASM_TSAN_SYMBOL macro for that). * To make the interceptors work, we ween to name the function "_wrap_setjmp" (added ASM_TSAN_SYMBOL_INTERCEPTOR for that). * Calling the original setjmp is done with a simple "jmp _setjmp". * __sigsetjmp doesn't exist on OS X. Differential Revision: http://reviews.llvm.org/D14947 llvm-svn: 254228
This commit is contained in:
parent
f12b925bb1
commit
f94bb99adc
|
@ -43,4 +43,16 @@
|
|||
# define CFI_RESTORE(reg)
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
# define ASM_HIDDEN(symbol) .hidden symbol
|
||||
# define ASM_TYPE_FUNCTION(symbol) .type symbol, @function
|
||||
# define ASM_SIZE(symbol) .size symbol, .-symbol
|
||||
# define ASM_TSAN_SYMBOL(symbol) symbol
|
||||
# define ASM_TSAN_SYMBOL_INTERCEPTOR(symbol) symbol
|
||||
#else
|
||||
# define ASM_HIDDEN(symbol)
|
||||
# define ASM_TYPE_FUNCTION(symbol)
|
||||
# define ASM_SIZE(symbol)
|
||||
# define ASM_TSAN_SYMBOL(symbol) _##symbol
|
||||
# define ASM_TSAN_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol
|
||||
#endif
|
||||
|
|
|
@ -95,11 +95,19 @@ add_compiler_rt_object_libraries(RTTsan_dynamic
|
|||
CFLAGS ${TSAN_RTL_CFLAGS})
|
||||
|
||||
if(APPLE)
|
||||
set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S)
|
||||
# Xcode will try to compile this file as C ('clang -x c'), and that will fail.
|
||||
if (${CMAKE_GENERATOR} STREQUAL "Xcode")
|
||||
enable_language(ASM)
|
||||
else()
|
||||
# Pass ASM file directly to the C++ compiler.
|
||||
set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES LANGUAGE C)
|
||||
endif()
|
||||
add_compiler_rt_runtime(clang_rt.tsan
|
||||
SHARED
|
||||
OS ${TSAN_SUPPORTED_OS}
|
||||
ARCHS ${TSAN_SUPPORTED_ARCH}
|
||||
SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES}
|
||||
SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES}
|
||||
OBJECT_LIBS RTInterception
|
||||
RTSanitizerCommon
|
||||
RTSanitizerCommonLibc
|
||||
|
|
|
@ -440,7 +440,7 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
|
|||
}
|
||||
|
||||
static void LongJmp(ThreadState *thr, uptr *env) {
|
||||
#if SANITIZER_FREEBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_MAC
|
||||
uptr mangled_sp = env[2];
|
||||
#elif defined(SANITIZER_LINUX)
|
||||
# ifdef __aarch64__
|
||||
|
@ -478,6 +478,11 @@ extern "C" void __tsan_setjmp(uptr sp, uptr mangled_sp) {
|
|||
SetJmp(cur_thread(), sp, mangled_sp);
|
||||
}
|
||||
|
||||
#if SANITIZER_MAC
|
||||
TSAN_INTERCEPTOR(int, setjmp, void *env);
|
||||
TSAN_INTERCEPTOR(int, _setjmp, void *env);
|
||||
TSAN_INTERCEPTOR(int, sigsetjmp, void *env);
|
||||
#else // SANITIZER_MAC
|
||||
// Not called. Merely to satisfy TSAN_INTERCEPT().
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
int __interceptor_setjmp(void *env);
|
||||
|
@ -516,6 +521,7 @@ DEFINE_REAL(int, setjmp, void *env)
|
|||
DEFINE_REAL(int, _setjmp, void *env)
|
||||
DEFINE_REAL(int, sigsetjmp, void *env)
|
||||
DEFINE_REAL(int, __sigsetjmp, void *env)
|
||||
#endif // SANITIZER_MAC
|
||||
|
||||
TSAN_INTERCEPTOR(void, longjmp, uptr *env, int val) {
|
||||
{
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#include "sanitizer_common/sanitizer_asm.h"
|
||||
#if !defined(__APPLE__)
|
||||
.section .text
|
||||
#else
|
||||
.section __TEXT,__text
|
||||
#endif
|
||||
|
||||
.hidden __tsan_trace_switch
|
||||
.globl __tsan_trace_switch_thunk
|
||||
__tsan_trace_switch_thunk:
|
||||
ASM_HIDDEN(__tsan_trace_switch)
|
||||
.globl ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk)
|
||||
ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk):
|
||||
CFI_STARTPROC
|
||||
# Save scratch registers.
|
||||
push %rax
|
||||
|
@ -42,7 +46,7 @@ __tsan_trace_switch_thunk:
|
|||
shr $4, %rsp # clear 4 lsb, align to 16
|
||||
shl $4, %rsp
|
||||
|
||||
call __tsan_trace_switch
|
||||
call ASM_TSAN_SYMBOL(__tsan_trace_switch)
|
||||
|
||||
# Unalign stack frame back.
|
||||
mov %rbx, %rsp # restore the original rsp
|
||||
|
@ -81,9 +85,9 @@ __tsan_trace_switch_thunk:
|
|||
ret
|
||||
CFI_ENDPROC
|
||||
|
||||
.hidden __tsan_report_race
|
||||
.globl __tsan_report_race_thunk
|
||||
__tsan_report_race_thunk:
|
||||
ASM_HIDDEN(__tsan_report_race)
|
||||
.globl ASM_TSAN_SYMBOL(__tsan_report_race_thunk)
|
||||
ASM_TSAN_SYMBOL(__tsan_report_race_thunk):
|
||||
CFI_STARTPROC
|
||||
# Save scratch registers.
|
||||
push %rax
|
||||
|
@ -122,7 +126,7 @@ __tsan_report_race_thunk:
|
|||
shr $4, %rsp # clear 4 lsb, align to 16
|
||||
shl $4, %rsp
|
||||
|
||||
call __tsan_report_race
|
||||
call ASM_TSAN_SYMBOL(__tsan_report_race)
|
||||
|
||||
# Unalign stack frame back.
|
||||
mov %rbx, %rsp # restore the original rsp
|
||||
|
@ -161,11 +165,13 @@ __tsan_report_race_thunk:
|
|||
ret
|
||||
CFI_ENDPROC
|
||||
|
||||
.hidden __tsan_setjmp
|
||||
ASM_HIDDEN(__tsan_setjmp)
|
||||
#if !defined(__APPLE__)
|
||||
.comm _ZN14__interception11real_setjmpE,8,8
|
||||
.globl setjmp
|
||||
.type setjmp, @function
|
||||
setjmp:
|
||||
#endif
|
||||
.globl ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)
|
||||
ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp))
|
||||
ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp):
|
||||
CFI_STARTPROC
|
||||
// save env parameter
|
||||
push %rdi
|
||||
|
@ -175,29 +181,38 @@ setjmp:
|
|||
#if defined(__FreeBSD__)
|
||||
lea 8(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
lea 16(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
#elif defined(__linux__)
|
||||
lea 16(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
|
||||
rol $0x11, %rsi
|
||||
#else
|
||||
# error "Unknown platform"
|
||||
#endif
|
||||
// call tsan interceptor
|
||||
call __tsan_setjmp
|
||||
call ASM_TSAN_SYMBOL(__tsan_setjmp)
|
||||
// restore env parameter
|
||||
pop %rdi
|
||||
CFI_ADJUST_CFA_OFFSET(-8)
|
||||
CFI_RESTORE(%rdi)
|
||||
// tail jump to libc setjmp
|
||||
movl $0, %eax
|
||||
#if !defined(__APPLE__)
|
||||
movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx
|
||||
jmp *(%rdx)
|
||||
#else
|
||||
jmp ASM_TSAN_SYMBOL(setjmp)
|
||||
#endif
|
||||
CFI_ENDPROC
|
||||
.size setjmp, .-setjmp
|
||||
ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp))
|
||||
|
||||
.comm _ZN14__interception12real__setjmpE,8,8
|
||||
.globl _setjmp
|
||||
.type _setjmp, @function
|
||||
_setjmp:
|
||||
.globl ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)
|
||||
ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp))
|
||||
ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp):
|
||||
CFI_STARTPROC
|
||||
// save env parameter
|
||||
push %rdi
|
||||
|
@ -207,29 +222,38 @@ _setjmp:
|
|||
#if defined(__FreeBSD__)
|
||||
lea 8(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
lea 16(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
#elif defined(__linux__)
|
||||
lea 16(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
|
||||
rol $0x11, %rsi
|
||||
#else
|
||||
# error "Unknown platform"
|
||||
#endif
|
||||
// call tsan interceptor
|
||||
call __tsan_setjmp
|
||||
call ASM_TSAN_SYMBOL(__tsan_setjmp)
|
||||
// restore env parameter
|
||||
pop %rdi
|
||||
CFI_ADJUST_CFA_OFFSET(-8)
|
||||
CFI_RESTORE(%rdi)
|
||||
// tail jump to libc setjmp
|
||||
movl $0, %eax
|
||||
#if !defined(__APPLE__)
|
||||
movq _ZN14__interception12real__setjmpE@GOTPCREL(%rip), %rdx
|
||||
jmp *(%rdx)
|
||||
#else
|
||||
jmp ASM_TSAN_SYMBOL(_setjmp)
|
||||
#endif
|
||||
CFI_ENDPROC
|
||||
.size _setjmp, .-_setjmp
|
||||
ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp))
|
||||
|
||||
.comm _ZN14__interception14real_sigsetjmpE,8,8
|
||||
.globl sigsetjmp
|
||||
.type sigsetjmp, @function
|
||||
sigsetjmp:
|
||||
.globl ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)
|
||||
ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp))
|
||||
ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp):
|
||||
CFI_STARTPROC
|
||||
// save env parameter
|
||||
push %rdi
|
||||
|
@ -246,14 +270,19 @@ sigsetjmp:
|
|||
#if defined(__FreeBSD__)
|
||||
lea 24(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
lea 32(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
#elif defined(__linux__)
|
||||
lea 32(%rsp), %rdi
|
||||
mov %rdi, %rsi
|
||||
xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
|
||||
rol $0x11, %rsi
|
||||
#else
|
||||
# error "Unknown platform"
|
||||
#endif
|
||||
// call tsan interceptor
|
||||
call __tsan_setjmp
|
||||
call ASM_TSAN_SYMBOL(__tsan_setjmp)
|
||||
// unalign stack frame
|
||||
add $8, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET(-8)
|
||||
|
@ -267,15 +296,20 @@ sigsetjmp:
|
|||
CFI_RESTORE(%rdi)
|
||||
// tail jump to libc sigsetjmp
|
||||
movl $0, %eax
|
||||
#if !defined(__APPLE__)
|
||||
movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx
|
||||
jmp *(%rdx)
|
||||
#else
|
||||
jmp ASM_TSAN_SYMBOL(setjmp)
|
||||
#endif
|
||||
CFI_ENDPROC
|
||||
.size sigsetjmp, .-sigsetjmp
|
||||
ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp))
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
.comm _ZN14__interception16real___sigsetjmpE,8,8
|
||||
.globl __sigsetjmp
|
||||
.type __sigsetjmp, @function
|
||||
__sigsetjmp:
|
||||
.globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)
|
||||
ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))
|
||||
ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp):
|
||||
CFI_STARTPROC
|
||||
// save env parameter
|
||||
push %rdi
|
||||
|
@ -299,7 +333,7 @@ __sigsetjmp:
|
|||
rol $0x11, %rsi
|
||||
#endif
|
||||
// call tsan interceptor
|
||||
call __tsan_setjmp
|
||||
call ASM_TSAN_SYMBOL(__tsan_setjmp)
|
||||
// unalign stack frame
|
||||
add $8, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET(-8)
|
||||
|
@ -316,7 +350,8 @@ __sigsetjmp:
|
|||
movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx
|
||||
jmp *(%rdx)
|
||||
CFI_ENDPROC
|
||||
.size __sigsetjmp, .-__sigsetjmp
|
||||
ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))
|
||||
#endif // !defined(__APPLE__)
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
/* We do not need executable stack. */
|
||||
|
|
Loading…
Reference in New Issue