From 14e92c2c62878b574e694bb0f495ec5e3fcb7b8a Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Thu, 5 Dec 2013 07:44:35 +0000 Subject: [PATCH] [sanitizer] support toolchains that don't understand CFI directives Summary: Support toolchains that don't understand CFI directives. Reviewers: dvyukov Reviewed By: dvyukov CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2336 llvm-svn: 196480 --- .../lib/sanitizer_common/sanitizer_asm.h | 40 +++ compiler-rt/lib/tsan/rtl/tsan_rtl.h | 5 +- compiler-rt/lib/tsan/rtl/tsan_rtl_amd64.S | 249 +++++++++--------- 3 files changed, 168 insertions(+), 126 deletions(-) create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_asm.h diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h new file mode 100644 index 000000000000..906012a96f11 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h @@ -0,0 +1,40 @@ +//===-- sanitizer_asm.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Various support for assemebler. +// +//===----------------------------------------------------------------------===// + +// Some toolchains do not support .cfi asm directives, so we have to hide +// them inside macros. +#if defined(__clang__) || \ + (defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)) + // GCC defined __GCC_HAVE_DWARF2_CFI_ASM if it supports CFI. + // Clang seems to support CFI by default (or not?). + // We need two versions of macros: for inline asm and standalone asm files. +# define CFI_INL_ADJUST_CFA_OFFSET(n) ".cfi_adjust_cfa_offset " #n ";" + +# define CFI_STARTPROC .cfi_startproc +# define CFI_ENDPROC .cfi_endproc +# define CFI_ADJUST_CFA_OFFSET(n) .cfi_adjust_cfa_offset n +# define CFI_REL_OFFSET(reg, n) .cfi_rel_offset reg, n +# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg +# define CFI_RESTORE(reg) .cfi_restore reg + +#else // No CFI +# define CFI_INL_ADJUST_CFA_OFFSET(n) +# define CFI_STARTPROC +# define CFI_ENDPROC +# define CFI_ADJUST_CFA_OFFSET(n) +# define CFI_REL_OFFSET(reg, n) +# define CFI_DEF_CFA_REGISTER(reg) +# define CFI_RESTORE(reg) +#endif + + diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 70e86200c37a..f7e4165de280 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -28,6 +28,7 @@ #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_internal.h" +#include "sanitizer_common/sanitizer_asm.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libignore.h" #include "sanitizer_common/sanitizer_suppressions.h" @@ -736,11 +737,11 @@ void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c); // so we create a reserve stack frame for it (1024b must be enough). #define HACKY_CALL(f) \ __asm__ __volatile__("sub $1024, %%rsp;" \ - ".cfi_adjust_cfa_offset 1024;" \ + CFI_INL_ADJUST_CFA_OFFSET(1024) \ ".hidden " #f "_thunk;" \ "call " #f "_thunk;" \ "add $1024, %%rsp;" \ - ".cfi_adjust_cfa_offset -1024;" \ + CFI_INL_ADJUST_CFA_OFFSET(-1024) \ ::: "memory", "cc"); #else #define HACKY_CALL(f) f() diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_amd64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_amd64.S index 11c75c72dbe5..11c19a79f224 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_amd64.S +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_amd64.S @@ -1,43 +1,44 @@ +#include "sanitizer_common/sanitizer_asm.h" .section .text .hidden __tsan_trace_switch .globl __tsan_trace_switch_thunk __tsan_trace_switch_thunk: - .cfi_startproc + CFI_STARTPROC # Save scratch registers. push %rax - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rax, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rax, 0) push %rcx - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rcx, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rcx, 0) push %rdx - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdx, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdx, 0) push %rsi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rsi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rsi, 0) push %rdi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) push %r8 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r8, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r8, 0) push %r9 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r9, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r9, 0) push %r10 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r10, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r10, 0) push %r11 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r11, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r11, 0) # Align stack frame. push %rbx # non-scratch - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rbx, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rbx, 0) mov %rsp, %rbx # save current rsp - .cfi_def_cfa_register %rbx + CFI_DEF_CFA_REGISTER(%rbx) shr $4, %rsp # clear 4 lsb, align to 16 shl $4, %rsp @@ -45,79 +46,79 @@ __tsan_trace_switch_thunk: # Unalign stack frame back. mov %rbx, %rsp # restore the original rsp - .cfi_def_cfa_register %rsp + CFI_DEF_CFA_REGISTER(%rsp) pop %rbx - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) # Restore scratch registers. pop %r11 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %r10 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %r9 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %r8 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rdi - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rsi - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rdx - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rcx - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rax - .cfi_adjust_cfa_offset -8 - .cfi_restore %rax - .cfi_restore %rbx - .cfi_restore %rcx - .cfi_restore %rdx - .cfi_restore %rsi - .cfi_restore %rdi - .cfi_restore %r8 - .cfi_restore %r9 - .cfi_restore %r10 - .cfi_restore %r11 + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rax) + CFI_RESTORE(%rbx) + CFI_RESTORE(%rcx) + CFI_RESTORE(%rdx) + CFI_RESTORE(%rsi) + CFI_RESTORE(%rdi) + CFI_RESTORE(%r8) + CFI_RESTORE(%r9) + CFI_RESTORE(%r10) + CFI_RESTORE(%r11) ret - .cfi_endproc + CFI_ENDPROC .hidden __tsan_report_race .globl __tsan_report_race_thunk __tsan_report_race_thunk: - .cfi_startproc + CFI_STARTPROC # Save scratch registers. push %rax - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rax, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rax, 0) push %rcx - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rcx, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rcx, 0) push %rdx - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdx, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdx, 0) push %rsi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rsi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rsi, 0) push %rdi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) push %r8 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r8, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r8, 0) push %r9 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r9, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r9, 0) push %r10 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r10, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r10, 0) push %r11 - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %r11, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%r11, 0) # Align stack frame. push %rbx # non-scratch - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rbx, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rbx, 0) mov %rsp, %rbx # save current rsp - .cfi_def_cfa_register %rbx + CFI_DEF_CFA_REGISTER(%rbx) shr $4, %rsp # clear 4 lsb, align to 16 shl $4, %rsp @@ -125,51 +126,51 @@ __tsan_report_race_thunk: # Unalign stack frame back. mov %rbx, %rsp # restore the original rsp - .cfi_def_cfa_register %rsp + CFI_DEF_CFA_REGISTER(%rsp) pop %rbx - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) # Restore scratch registers. pop %r11 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %r10 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %r9 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %r8 - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rdi - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rsi - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rdx - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rcx - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) pop %rax - .cfi_adjust_cfa_offset -8 - .cfi_restore %rax - .cfi_restore %rbx - .cfi_restore %rcx - .cfi_restore %rdx - .cfi_restore %rsi - .cfi_restore %rdi - .cfi_restore %r8 - .cfi_restore %r9 - .cfi_restore %r10 - .cfi_restore %r11 + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rax) + CFI_RESTORE(%rbx) + CFI_RESTORE(%rcx) + CFI_RESTORE(%rdx) + CFI_RESTORE(%rsi) + CFI_RESTORE(%rdi) + CFI_RESTORE(%r8) + CFI_RESTORE(%r9) + CFI_RESTORE(%r10) + CFI_RESTORE(%r11) ret - .cfi_endproc + CFI_ENDPROC .hidden __tsan_setjmp .comm _ZN14__interception11real_setjmpE,8,8 .globl setjmp .type setjmp, @function setjmp: - .cfi_startproc + CFI_STARTPROC // save env parameter push %rdi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) // obtain %rsp lea 16(%rsp), %rdi mov %rdi, %rsi @@ -179,24 +180,24 @@ setjmp: call __tsan_setjmp // restore env parameter pop %rdi - .cfi_adjust_cfa_offset -8 - .cfi_restore %rdi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rdi) // tail jump to libc setjmp movl $0, %eax movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) - .cfi_endproc + CFI_ENDPROC .size setjmp, .-setjmp .comm _ZN14__interception12real__setjmpE,8,8 .globl _setjmp .type _setjmp, @function _setjmp: - .cfi_startproc + CFI_STARTPROC // save env parameter push %rdi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) // obtain %rsp lea 16(%rsp), %rdi mov %rdi, %rsi @@ -206,31 +207,31 @@ _setjmp: call __tsan_setjmp // restore env parameter pop %rdi - .cfi_adjust_cfa_offset -8 - .cfi_restore %rdi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rdi) // tail jump to libc setjmp movl $0, %eax movq _ZN14__interception12real__setjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) - .cfi_endproc + CFI_ENDPROC .size _setjmp, .-_setjmp .comm _ZN14__interception14real_sigsetjmpE,8,8 .globl sigsetjmp .type sigsetjmp, @function sigsetjmp: - .cfi_startproc + CFI_STARTPROC // save env parameter push %rdi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) // save savesigs parameter push %rsi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rsi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rsi, 0) // align stack frame sub $8, %rsp - .cfi_adjust_cfa_offset 8 + CFI_ADJUST_CFA_OFFSET(8) // obtain %rsp lea 32(%rsp), %rdi mov %rdi, %rsi @@ -240,38 +241,38 @@ sigsetjmp: call __tsan_setjmp // unalign stack frame add $8, %rsp - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) // restore savesigs parameter pop %rsi - .cfi_adjust_cfa_offset -8 - .cfi_restore %rsi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rsi) // restore env parameter pop %rdi - .cfi_adjust_cfa_offset -8 - .cfi_restore %rdi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rdi) // tail jump to libc sigsetjmp movl $0, %eax movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) - .cfi_endproc + CFI_ENDPROC .size sigsetjmp, .-sigsetjmp .comm _ZN14__interception16real___sigsetjmpE,8,8 .globl __sigsetjmp .type __sigsetjmp, @function __sigsetjmp: - .cfi_startproc + CFI_STARTPROC // save env parameter push %rdi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rdi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) // save savesigs parameter push %rsi - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset %rsi, 0 + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rsi, 0) // align stack frame sub $8, %rsp - .cfi_adjust_cfa_offset 8 + CFI_ADJUST_CFA_OFFSET(8) // obtain %rsp lea 32(%rsp), %rdi mov %rdi, %rsi @@ -281,20 +282,20 @@ __sigsetjmp: call __tsan_setjmp // unalign stack frame add $8, %rsp - .cfi_adjust_cfa_offset -8 + CFI_ADJUST_CFA_OFFSET(-8) // restore savesigs parameter pop %rsi - .cfi_adjust_cfa_offset -8 - .cfi_restore %rsi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rsi) // restore env parameter pop %rdi - .cfi_adjust_cfa_offset -8 - .cfi_restore %rdi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rdi) // tail jump to libc sigsetjmp movl $0, %eax movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) - .cfi_endproc + CFI_ENDPROC .size __sigsetjmp, .-__sigsetjmp #ifdef __linux__