forked from OSchip/llvm-project
[compiler-rt] [tsan] Enable intercept setjmp/longjmp for AArch64
This patch adds assembly routines to enable setjmp/longjmp for aarch64 on linux. It fixes: * test/tsan/longjmp2.cc * test/tsan/longjmp3.cc * test/tsan/longjmp4.cc * test/tsan/signal_longjmp.cc I also checked with perlbench from specpu2006 (it fails to run with missing setjmp/longjmp intrumentation). llvm-svn: 253205
This commit is contained in:
parent
bdf8751609
commit
2f7f5e3535
|
@ -23,8 +23,11 @@
|
||||||
# define CFI_STARTPROC .cfi_startproc
|
# define CFI_STARTPROC .cfi_startproc
|
||||||
# define CFI_ENDPROC .cfi_endproc
|
# define CFI_ENDPROC .cfi_endproc
|
||||||
# define CFI_ADJUST_CFA_OFFSET(n) .cfi_adjust_cfa_offset n
|
# define CFI_ADJUST_CFA_OFFSET(n) .cfi_adjust_cfa_offset n
|
||||||
|
# define CFI_DEF_CFA_OFFSET(n) .cfi_def_cfa_offset n
|
||||||
# define CFI_REL_OFFSET(reg, n) .cfi_rel_offset reg, n
|
# define CFI_REL_OFFSET(reg, n) .cfi_rel_offset reg, n
|
||||||
|
# define CFI_OFFSET(reg, n) .cfi_offset reg, n
|
||||||
# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
|
# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
|
||||||
|
# define CFI_DEF_CFA(reg, n) .cfi_def_cfa reg, n
|
||||||
# define CFI_RESTORE(reg) .cfi_restore reg
|
# define CFI_RESTORE(reg) .cfi_restore reg
|
||||||
|
|
||||||
#else // No CFI
|
#else // No CFI
|
||||||
|
@ -32,8 +35,11 @@
|
||||||
# define CFI_STARTPROC
|
# define CFI_STARTPROC
|
||||||
# define CFI_ENDPROC
|
# define CFI_ENDPROC
|
||||||
# define CFI_ADJUST_CFA_OFFSET(n)
|
# define CFI_ADJUST_CFA_OFFSET(n)
|
||||||
|
# define CFI_DEF_CFA_OFFSET(n)
|
||||||
# define CFI_REL_OFFSET(reg, n)
|
# define CFI_REL_OFFSET(reg, n)
|
||||||
|
# define CFI_OFFSET(reg, n)
|
||||||
# define CFI_DEF_CFA_REGISTER(reg)
|
# define CFI_DEF_CFA_REGISTER(reg)
|
||||||
|
# define CFI_DEF_CFA(reg, n)
|
||||||
# define CFI_RESTORE(reg)
|
# define CFI_RESTORE(reg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,11 @@ else()
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
|
||||||
COMMENT "Checking TSan Go runtime..."
|
COMMENT "Checking TSan Go runtime..."
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
elseif(arch STREQUAL "aarch64")
|
||||||
|
set(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S)
|
||||||
|
# Pass ASM file directly to the C++ compiler.
|
||||||
|
set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES
|
||||||
|
LANGUAGE C)
|
||||||
else()
|
else()
|
||||||
set(TSAN_ASM_SOURCES)
|
set(TSAN_ASM_SOURCES)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -451,8 +451,12 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
|
||||||
static void LongJmp(ThreadState *thr, uptr *env) {
|
static void LongJmp(ThreadState *thr, uptr *env) {
|
||||||
#if SANITIZER_FREEBSD
|
#if SANITIZER_FREEBSD
|
||||||
uptr mangled_sp = env[2];
|
uptr mangled_sp = env[2];
|
||||||
#else
|
#elif defined(SANITIZER_LINUX)
|
||||||
|
# ifdef __aarch64__
|
||||||
|
uptr mangled_sp = env[13];
|
||||||
|
# else
|
||||||
uptr mangled_sp = env[6];
|
uptr mangled_sp = env[6];
|
||||||
|
# endif
|
||||||
#endif // SANITIZER_FREEBSD
|
#endif // SANITIZER_FREEBSD
|
||||||
// Find the saved buf by mangled_sp.
|
// Find the saved buf by mangled_sp.
|
||||||
for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
|
for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
#include "sanitizer_common/sanitizer_asm.h"
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.hidden __tsan_setjmp
|
||||||
|
.comm _ZN14__interception11real_setjmpE,8,8
|
||||||
|
.type setjmp, @function
|
||||||
|
setjmp:
|
||||||
|
CFI_STARTPROC
|
||||||
|
|
||||||
|
// save env parameters for function call
|
||||||
|
stp x29, x30, [sp, -32]!
|
||||||
|
CFI_DEF_CFA_OFFSET (32)
|
||||||
|
CFI_OFFSET (29, -32)
|
||||||
|
CFI_OFFSET (30, -24)
|
||||||
|
|
||||||
|
// Adjust the SP for previous frame
|
||||||
|
add x29, sp, 0
|
||||||
|
CFI_DEF_CFA_REGISTER (29)
|
||||||
|
|
||||||
|
// Save jmp_buf
|
||||||
|
str x19, [sp, 16]
|
||||||
|
CFI_OFFSET (19, -16)
|
||||||
|
mov x19, x0
|
||||||
|
|
||||||
|
// SP pointer mangling (see glibc setjmp)
|
||||||
|
adrp x2, :got:__pointer_chk_guard
|
||||||
|
ldr x2, [x2, #:got_lo12:__pointer_chk_guard]
|
||||||
|
add x0, x29, 32
|
||||||
|
ldr x2, [x2]
|
||||||
|
eor x1, x2, x0
|
||||||
|
|
||||||
|
// call tsan interceptor
|
||||||
|
bl __tsan_setjmp
|
||||||
|
|
||||||
|
// restore env parameter
|
||||||
|
mov x0, x19
|
||||||
|
ldr x19, [sp, 16]
|
||||||
|
ldp x29, x30, [sp], 32
|
||||||
|
CFI_RESTORE (30)
|
||||||
|
CFI_RESTORE (19)
|
||||||
|
CFI_DEF_CFA (31, 0)
|
||||||
|
|
||||||
|
// tail jump to libc setjmp
|
||||||
|
adrp x1, :got:_ZN14__interception11real_setjmpE
|
||||||
|
ldr x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
|
||||||
|
ldr x1, [x1]
|
||||||
|
br x1
|
||||||
|
|
||||||
|
CFI_ENDPROC
|
||||||
|
.size setjmp, .-setjmp
|
||||||
|
|
||||||
|
.comm _ZN14__interception12real__setjmpE,8,8
|
||||||
|
.globl _setjmp
|
||||||
|
.type _setjmp, @function
|
||||||
|
_setjmp:
|
||||||
|
CFI_STARTPROC
|
||||||
|
|
||||||
|
// save env parameters for function call
|
||||||
|
stp x29, x30, [sp, -32]!
|
||||||
|
CFI_DEF_CFA_OFFSET (32)
|
||||||
|
CFI_OFFSET (29, -32)
|
||||||
|
CFI_OFFSET (30, -24)
|
||||||
|
|
||||||
|
// Adjust the SP for previous frame
|
||||||
|
add x29, sp, 0
|
||||||
|
CFI_DEF_CFA_REGISTER (29)
|
||||||
|
|
||||||
|
// Save jmp_buf
|
||||||
|
str x19, [sp, 16]
|
||||||
|
CFI_OFFSET (19, -16)
|
||||||
|
mov x19, x0
|
||||||
|
|
||||||
|
// SP pointer mangling (see glibc setjmp)
|
||||||
|
adrp x2, :got:__pointer_chk_guard
|
||||||
|
ldr x2, [x2, #:got_lo12:__pointer_chk_guard]
|
||||||
|
add x0, x29, 32
|
||||||
|
ldr x2, [x2]
|
||||||
|
eor x1, x2, x0
|
||||||
|
|
||||||
|
// call tsan interceptor
|
||||||
|
bl __tsan_setjmp
|
||||||
|
|
||||||
|
// Restore jmp_buf parameter
|
||||||
|
mov x0, x19
|
||||||
|
ldr x19, [sp, 16]
|
||||||
|
ldp x29, x30, [sp], 32
|
||||||
|
CFI_RESTORE (30)
|
||||||
|
CFI_RESTORE (19)
|
||||||
|
CFI_DEF_CFA (31, 0)
|
||||||
|
|
||||||
|
// tail jump to libc setjmp
|
||||||
|
adrp x1, :got:_ZN14__interception12real__setjmpE
|
||||||
|
ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
|
||||||
|
ldr x1, [x1]
|
||||||
|
br x1
|
||||||
|
|
||||||
|
CFI_ENDPROC
|
||||||
|
.size _setjmp, .-_setjmp
|
||||||
|
|
||||||
|
.comm _ZN14__interception14real_sigsetjmpE,8,8
|
||||||
|
.globl sigsetjmp
|
||||||
|
.type sigsetjmp, @function
|
||||||
|
sigsetjmp:
|
||||||
|
CFI_STARTPROC
|
||||||
|
|
||||||
|
// save env parameters for function call
|
||||||
|
stp x29, x30, [sp, -32]!
|
||||||
|
CFI_DEF_CFA_OFFSET (32)
|
||||||
|
CFI_OFFSET (29, -32)
|
||||||
|
CFI_OFFSET (30, -24)
|
||||||
|
|
||||||
|
// Adjust the SP for previous frame
|
||||||
|
add x29, sp, 0
|
||||||
|
CFI_DEF_CFA_REGISTER (29)
|
||||||
|
|
||||||
|
// Save jmp_buf and savesigs
|
||||||
|
stp x19, x20, [sp, 16]
|
||||||
|
CFI_OFFSET (19, -16)
|
||||||
|
CFI_OFFSET (20, -8)
|
||||||
|
mov w20, w1
|
||||||
|
mov x19, x0
|
||||||
|
|
||||||
|
// SP pointer mangling (see glibc setjmp)
|
||||||
|
adrp x2, :got:__pointer_chk_guard
|
||||||
|
ldr x2, [x2, #:got_lo12:__pointer_chk_guard]
|
||||||
|
add x0, x29, 32
|
||||||
|
ldr x2, [x2]
|
||||||
|
eor x1, x2, x0
|
||||||
|
|
||||||
|
// call tsan interceptor
|
||||||
|
bl __tsan_setjmp
|
||||||
|
|
||||||
|
// restore env parameter
|
||||||
|
mov w1, w20
|
||||||
|
mov x0, x19
|
||||||
|
ldp x19, x20, [sp, 16]
|
||||||
|
ldp x29, x30, [sp], 32
|
||||||
|
CFI_RESTORE (30)
|
||||||
|
CFI_RESTORE (29)
|
||||||
|
CFI_RESTORE (19)
|
||||||
|
CFI_RESTORE (20)
|
||||||
|
CFI_DEF_CFA (31, 0)
|
||||||
|
|
||||||
|
// tail jump to libc sigsetjmp
|
||||||
|
adrp x2, :got:_ZN14__interception14real_sigsetjmpE
|
||||||
|
ldr x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
|
||||||
|
ldr x2, [x2]
|
||||||
|
br x2
|
||||||
|
CFI_ENDPROC
|
||||||
|
.size sigsetjmp, .-sigsetjmp
|
||||||
|
|
||||||
|
.comm _ZN14__interception16real___sigsetjmpE,8,8
|
||||||
|
.globl __sigsetjmp
|
||||||
|
.type __sigsetjmp, @function
|
||||||
|
__sigsetjmp:
|
||||||
|
CFI_STARTPROC
|
||||||
|
|
||||||
|
// save env parameters for function call
|
||||||
|
stp x29, x30, [sp, -32]!
|
||||||
|
CFI_DEF_CFA_OFFSET (32)
|
||||||
|
CFI_OFFSET (29, -32)
|
||||||
|
CFI_OFFSET (30, -24)
|
||||||
|
|
||||||
|
// Adjust the SP for previous frame
|
||||||
|
add x29, sp, 0
|
||||||
|
CFI_DEF_CFA_REGISTER (29)
|
||||||
|
|
||||||
|
// Save jmp_buf and savesigs
|
||||||
|
stp x19, x20, [sp, 16]
|
||||||
|
CFI_OFFSET (19, -16)
|
||||||
|
CFI_OFFSET (20, -8)
|
||||||
|
mov w20, w1
|
||||||
|
mov x19, x0
|
||||||
|
|
||||||
|
// SP pointer mangling (see glibc setjmp)
|
||||||
|
adrp x2, :got:__pointer_chk_guard
|
||||||
|
ldr x2, [x2, #:got_lo12:__pointer_chk_guard]
|
||||||
|
add x0, x29, 32
|
||||||
|
ldr x2, [x2]
|
||||||
|
eor x1, x2, x0
|
||||||
|
|
||||||
|
// call tsan interceptor
|
||||||
|
bl __tsan_setjmp
|
||||||
|
|
||||||
|
mov w1, w20
|
||||||
|
mov x0, x19
|
||||||
|
ldp x19, x20, [sp, 16]
|
||||||
|
ldp x29, x30, [sp], 32
|
||||||
|
CFI_RESTORE (30)
|
||||||
|
CFI_RESTORE (29)
|
||||||
|
CFI_RESTORE (19)
|
||||||
|
CFI_RESTORE (20)
|
||||||
|
CFI_DEF_CFA (31, 0)
|
||||||
|
|
||||||
|
// tail jump to libc __sigsetjmp
|
||||||
|
adrp x2, :got:_ZN14__interception16real___sigsetjmpE
|
||||||
|
ldr x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
|
||||||
|
ldr x2, [x2]
|
||||||
|
br x2
|
||||||
|
CFI_ENDPROC
|
||||||
|
.size __sigsetjmp, .-__sigsetjmp
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* We do not need executable stack. */
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
#endif
|
|
@ -1,8 +1,7 @@
|
||||||
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||||
|
|
||||||
// Longjmp assembly has not been implemented for mips64 or aarch64 yet
|
// Longjmp assembly has not been implemented for mips64 yet
|
||||||
// XFAIL: mips64
|
// XFAIL: mips64
|
||||||
// XFAIL: aarch64
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||||
|
|
||||||
// Longjmp assembly has not been implemented for mips64 or aarch64 yet
|
// Longjmp assembly has not been implemented for mips64 yet
|
||||||
// XFAIL: mips64
|
// XFAIL: mips64
|
||||||
// XFAIL: aarch64
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
|
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
|
||||||
|
|
||||||
// Longjmp assembly has not been implemented for mips64 or aarch64 yet
|
// Longjmp assembly has not been implemented for mips64 yet
|
||||||
// XFAIL: mips64
|
// XFAIL: mips64
|
||||||
// XFAIL: aarch64
|
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
|
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
|
||||||
|
|
||||||
// Longjmp assembly has not been implemented for mips64 or aarch64 yet
|
// Longjmp assembly has not been implemented for mips64 yet
|
||||||
// XFAIL: mips64
|
// XFAIL: mips64
|
||||||
// XFAIL: aarch64
|
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
// Test case for longjumping out of signal handler:
|
// Test case for longjumping out of signal handler:
|
||||||
// https://code.google.com/p/thread-sanitizer/issues/detail?id=75
|
// https://code.google.com/p/thread-sanitizer/issues/detail?id=75
|
||||||
|
|
||||||
// Longjmp assembly has not been implemented for mips64 or aarch64 yet
|
// Longjmp assembly has not been implemented for mips64 yet
|
||||||
// XFAIL: mips64
|
// XFAIL: mips64
|
||||||
// XFAIL: aarch64
|
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
Loading…
Reference in New Issue