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_ENDPROC .cfi_endproc
|
||||
# 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_OFFSET(reg, n) .cfi_offset reg, n
|
||||
# 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
|
||||
|
||||
#else // No CFI
|
||||
|
@ -32,8 +35,11 @@
|
|||
# define CFI_STARTPROC
|
||||
# define CFI_ENDPROC
|
||||
# define CFI_ADJUST_CFA_OFFSET(n)
|
||||
# define CFI_DEF_CFA_OFFSET(n)
|
||||
# define CFI_REL_OFFSET(reg, n)
|
||||
# define CFI_OFFSET(reg, n)
|
||||
# define CFI_DEF_CFA_REGISTER(reg)
|
||||
# define CFI_DEF_CFA(reg, n)
|
||||
# define CFI_RESTORE(reg)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -121,6 +121,11 @@ else()
|
|||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
|
||||
COMMENT "Checking TSan Go runtime..."
|
||||
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()
|
||||
set(TSAN_ASM_SOURCES)
|
||||
endif()
|
||||
|
|
|
@ -451,8 +451,12 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
|
|||
static void LongJmp(ThreadState *thr, uptr *env) {
|
||||
#if SANITIZER_FREEBSD
|
||||
uptr mangled_sp = env[2];
|
||||
#else
|
||||
#elif defined(SANITIZER_LINUX)
|
||||
# ifdef __aarch64__
|
||||
uptr mangled_sp = env[13];
|
||||
# else
|
||||
uptr mangled_sp = env[6];
|
||||
# endif
|
||||
#endif // SANITIZER_FREEBSD
|
||||
// Find the saved buf by mangled_sp.
|
||||
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
|
||||
|
||||
// Longjmp assembly has not been implemented for mips64 or aarch64 yet
|
||||
// Longjmp assembly has not been implemented for mips64 yet
|
||||
// XFAIL: mips64
|
||||
// XFAIL: aarch64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
// 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: aarch64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
// 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: aarch64
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
// 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: aarch64
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
// Test case for longjumping out of signal handler:
|
||||
// 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: aarch64
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
|
Loading…
Reference in New Issue