From c4c16f745651177876f689b848586aa5a9f6a812 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Thu, 5 Dec 2013 10:28:59 +0000 Subject: [PATCH] libsanitizer merge from upstream r196489 From-SVN: r205700 --- libsanitizer/ChangeLog | 5 + libsanitizer/MERGE | 2 +- libsanitizer/asan/asan_mapping.h | 4 +- libsanitizer/asan/asan_stack.cc | 8 + libsanitizer/asan/asan_stack.h | 9 +- .../include/sanitizer/common_interface_defs.h | 3 + libsanitizer/merge.sh | 2 +- .../sanitizer_common/sanitizer_common.cc | 7 + .../sanitizer_common/sanitizer_common.h | 5 +- .../sanitizer_common_interceptors.inc | 17 + .../sanitizer_platform_interceptors.h | 1 + .../sanitizer_platform_limits_posix.h | 24 +- .../sanitizer_common/sanitizer_posix.cc | 18 +- .../sanitizer_stoptheworld_linux_libcdep.cc | 15 + libsanitizer/tsan/tsan_rtl.h | 5 +- libsanitizer/tsan/tsan_rtl_amd64.S | 318 +++++++++++++----- libsanitizer/tsan/tsan_stat.cc | 1 + libsanitizer/tsan/tsan_stat.h | 1 + 18 files changed, 329 insertions(+), 116 deletions(-) diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index 0c4c61feb0ce..0af33d012ed8 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,8 @@ +2013-12-05 Kostya Serebryany + + * All source files: Merge from upstream r196489. + * merge.sh: Add *.S to the list of merged files. + 2013-12-05 Yury Gribov PR sanitizer/59368 diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE index 084cd2d4ee6e..4688f0c8693f 100644 --- a/libsanitizer/MERGE +++ b/libsanitizer/MERGE @@ -1,4 +1,4 @@ -196090 +196489 The first line of this file holds the svn revision number of the last merge done from the master library sources. diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index fd5c2039bcac..1e37bc26e945 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -63,8 +63,8 @@ static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 -extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale; -extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset; +extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale; +extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset; # define SHADOW_SCALE (__asan_mapping_scale) # define SHADOW_OFFSET (__asan_mapping_offset) #else diff --git a/libsanitizer/asan/asan_stack.cc b/libsanitizer/asan/asan_stack.cc index 93671a03a928..24cccbd196e3 100644 --- a/libsanitizer/asan/asan_stack.cc +++ b/libsanitizer/asan/asan_stack.cc @@ -43,3 +43,11 @@ bool __asan_symbolize(const void *pc, char *out_buffer, int out_size) { return false; } #endif + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_print_stack_trace() { + using namespace __asan; + PRINT_CURRENT_STACK(); +} +} // extern "C" diff --git a/libsanitizer/asan/asan_stack.h b/libsanitizer/asan/asan_stack.h index c929c887d06b..df7a9805f92f 100644 --- a/libsanitizer/asan/asan_stack.h +++ b/libsanitizer/asan/asan_stack.h @@ -75,11 +75,10 @@ void PrintStack(const uptr *trace, uptr size); #define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC -#define PRINT_CURRENT_STACK() \ - { \ - GET_STACK_TRACE(kStackTraceMax, \ - common_flags()->fast_unwind_on_fatal); \ - PrintStack(&stack); \ +#define PRINT_CURRENT_STACK() \ + { \ + GET_STACK_TRACE_FATAL_HERE; \ + PrintStack(&stack); \ } #endif // ASAN_STACK_H diff --git a/libsanitizer/include/sanitizer/common_interface_defs.h b/libsanitizer/include/sanitizer/common_interface_defs.h index 956cb86d697a..db8b3b543e3d 100644 --- a/libsanitizer/include/sanitizer/common_interface_defs.h +++ b/libsanitizer/include/sanitizer/common_interface_defs.h @@ -83,6 +83,9 @@ extern "C" { const void *old_mid, const void *new_mid); + // Print the stack trace leading to this call. Useful for debugging user code. + void __sanitizer_print_stack_trace(); + #ifdef __cplusplus } // extern "C" #endif diff --git a/libsanitizer/merge.sh b/libsanitizer/merge.sh index aae8eb41f7d0..29e444248f15 100755 --- a/libsanitizer/merge.sh +++ b/libsanitizer/merge.sh @@ -16,7 +16,7 @@ get_current_rev() { } list_files() { - (cd $1; ls *.{cc,h,inc} 2> /dev/null) + (cd $1; ls *.{cc,h,inc,S} 2> /dev/null) } diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cc index bf73dc6339b6..0d93527aa5e5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common.cc @@ -40,6 +40,13 @@ char report_path_prefix[sizeof(report_path_prefix)]; // child thread will be different from |report_fd_pid|. uptr report_fd_pid = 0; +// PID of the tracer task in StopTheWorld. It shares the address space with the +// main process, but has a different PID and thus requires special handling. +uptr stoptheworld_tracer_pid = 0; +// Cached pid of parent process - if the parent process dies, we want to keep +// writing to the same log file. +uptr stoptheworld_tracer_ppid = 0; + static DieCallbackType DieCallback; void SetDieCallback(DieCallbackType callback) { DieCallback = callback; diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h index 833c2b07e35c..07d1b63db584 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.h +++ b/libsanitizer/sanitizer_common/sanitizer_common.h @@ -134,6 +134,8 @@ extern fd_t report_fd; extern bool log_to_file; extern char report_path_prefix[4096]; extern uptr report_fd_pid; +extern uptr stoptheworld_tracer_pid; +extern uptr stoptheworld_tracer_ppid; uptr OpenFile(const char *filename, bool write); // Opens the file 'file_name" and reads up to 'max_len' bytes. @@ -318,8 +320,7 @@ template class InternalMmapVector { public: explicit InternalMmapVector(uptr initial_capacity) { - CHECK_GT(initial_capacity, 0); - capacity_ = initial_capacity; + capacity_ = Max(initial_capacity, (uptr)1); size_ = 0; data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVector"); } diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index 45b12fcaf16e..e301dc17bd35 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -58,6 +58,22 @@ #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) #endif +#if SANITIZER_INTERCEPT_TEXTDOMAIN +INTERCEPTOR(char*, textdomain, const char *domainname) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname); + char* domain = REAL(textdomain)(domainname); + if (domain) { + COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, domain, + REAL(strlen)(domain) + 1); + } + return domain; +} +#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain) +#else +#define INIT_TEXTDOMAIN +#endif + #if SANITIZER_INTERCEPT_STRCMP static inline int CharCmpX(unsigned char c1, unsigned char c2) { return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; @@ -2891,6 +2907,7 @@ INTERCEPTOR(__sanitizer_clock_t, times, void *tms) { #endif #define SANITIZER_COMMON_INTERCEPTORS_INIT \ + INIT_TEXTDOMAIN; \ INIT_STRCMP; \ INIT_STRNCMP; \ INIT_STRCASECMP; \ diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h index b6dcbe9e8082..f37d84b041d8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h @@ -46,6 +46,7 @@ #endif # define SANITIZER_INTERCEPT_STRCMP 1 +# define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID # define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h index 3bb8dc1114ad..f98ebea79f4d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -140,23 +140,32 @@ namespace __sanitizer { int gid; int cuid; int cgid; -#ifdef __powerpc64__ +#ifdef __powerpc__ unsigned mode; unsigned __seq; + u64 __unused1; + u64 __unused2; #else unsigned short mode; unsigned short __pad1; unsigned short __seq; unsigned short __pad2; +#if defined(__x86_64__) && !defined(_LP64) + u64 __unused1; + u64 __unused2; +#else + unsigned long __unused1; + unsigned long __unused2; +#endif #endif - uptr __unused1; - uptr __unused2; }; struct __sanitizer_shmid_ds { __sanitizer_ipc_perm shm_perm; #ifndef __powerpc__ uptr shm_segsz; + #elif !defined(__powerpc64__) + uptr __unused0; #endif uptr shm_atime; #ifndef _LP64 @@ -288,17 +297,20 @@ namespace __sanitizer { typedef long __sanitizer_clock_t; #if SANITIZER_LINUX -#if defined(_LP64) || defined(__x86_64__) +#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) typedef unsigned __sanitizer___kernel_uid_t; typedef unsigned __sanitizer___kernel_gid_t; - typedef long long __sanitizer___kernel_off_t; #else typedef unsigned short __sanitizer___kernel_uid_t; typedef unsigned short __sanitizer___kernel_gid_t; +#endif +#if defined(__x86_64__) && !defined(_LP64) + typedef long long __sanitizer___kernel_off_t; +#else typedef long __sanitizer___kernel_off_t; #endif -#if defined(__powerpc64__) +#if defined(__powerpc__) typedef unsigned int __sanitizer___kernel_old_uid_t; typedef unsigned int __sanitizer___kernel_old_gid_t; #else diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cc b/libsanitizer/sanitizer_common/sanitizer_posix.cc index 6d999e919613..ef5cb0b03b8e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_posix.cc @@ -196,10 +196,15 @@ char *FindPathToBinary(const char *name) { } void MaybeOpenReportFile() { - if (!log_to_file || (report_fd_pid == internal_getpid())) return; + if (!log_to_file) return; + uptr pid = internal_getpid(); + // If in tracer, use the parent's file. + if (pid == stoptheworld_tracer_pid) + pid = stoptheworld_tracer_ppid; + if (report_fd_pid == pid) return; InternalScopedBuffer report_path_full(4096); internal_snprintf(report_path_full.data(), report_path_full.size(), - "%s.%d", report_path_prefix, internal_getpid()); + "%s.%d", report_path_prefix, pid); uptr openrv = OpenFile(report_path_full.data(), true); if (internal_iserror(openrv)) { report_fd = kStderrFd; @@ -212,7 +217,7 @@ void MaybeOpenReportFile() { internal_close(report_fd); } report_fd = openrv; - report_fd_pid = internal_getpid(); + report_fd_pid = pid; } void RawWrite(const char *buffer) { @@ -228,12 +233,11 @@ void RawWrite(const char *buffer) { bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) { uptr s, e, off, prot; - InternalMmapVector fn(4096); - fn.push_back(0); + InternalScopedString buff(4096); MemoryMappingLayout proc_maps(/*cache_enabled*/false); - while (proc_maps.Next(&s, &e, &off, &fn[0], fn.capacity(), &prot)) { + while (proc_maps.Next(&s, &e, &off, buff.data(), buff.size(), &prot)) { if ((prot & MemoryMappingLayout::kProtectionExecute) != 0 - && internal_strcmp(module, &fn[0]) == 0) { + && internal_strcmp(module, buff.data()) == 0) { *start = s; *end = e; return true; diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index 2b3dd29591e8..6ee63ec31686 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -354,6 +354,20 @@ class StopTheWorldScope { int process_was_dumpable_; }; +// When sanitizer output is being redirected to file (i.e. by using log_path), +// the tracer should write to the parent's log instead of trying to open a new +// file. Alert the logging code to the fact that we have a tracer. +struct ScopedSetTracerPID { + explicit ScopedSetTracerPID(uptr tracer_pid) { + stoptheworld_tracer_pid = tracer_pid; + stoptheworld_tracer_ppid = internal_getpid(); + } + ~ScopedSetTracerPID() { + stoptheworld_tracer_pid = 0; + stoptheworld_tracer_ppid = 0; + } +}; + void StopTheWorld(StopTheWorldCallback callback, void *argument) { StopTheWorldScope in_stoptheworld; // Prepare the arguments for TracerThread. @@ -377,6 +391,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) { Report("Failed spawning a tracer thread (errno %d).\n", local_errno); tracer_thread_argument.mutex.Unlock(); } else { + ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid); // On some systems we have to explicitly declare that we want to be traced // by the tracer thread. #ifdef PR_SET_PTRACER diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h index 45ed096efb85..20493ea4d3b9 100644 --- a/libsanitizer/tsan/tsan_rtl.h +++ b/libsanitizer/tsan/tsan_rtl.h @@ -26,6 +26,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" @@ -734,11 +735,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/libsanitizer/tsan/tsan_rtl_amd64.S b/libsanitizer/tsan/tsan_rtl_amd64.S index aee650d9f4e6..71a2ecda9dda 100644 --- a/libsanitizer/tsan/tsan_rtl_amd64.S +++ b/libsanitizer/tsan/tsan_rtl_amd64.S @@ -1,42 +1,42 @@ -.section .text - +#include "sanitizer_common/sanitizer_asm.h" +.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 @@ -44,78 +44,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 @@ -123,40 +124,177 @@ __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 + // save env parameter + push %rdi + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) + // obtain %rsp + lea 16(%rsp), %rdi + mov %rdi, %rsi + xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) + rol $0x11, %rsi + // call tsan interceptor + call __tsan_setjmp + // restore env parameter + pop %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 +.size setjmp, .-setjmp + +.comm _ZN14__interception12real__setjmpE,8,8 +.globl _setjmp +.type _setjmp, @function +_setjmp: + CFI_STARTPROC + // save env parameter + push %rdi + CFI_ADJUST_CFA_OFFSET(8) + CFI_REL_OFFSET(%rdi, 0) + // obtain %rsp + lea 16(%rsp), %rdi + mov %rdi, %rsi + xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) + rol $0x11, %rsi + // call tsan interceptor + call __tsan_setjmp + // restore env parameter + pop %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 +.size _setjmp, .-_setjmp + +.comm _ZN14__interception14real_sigsetjmpE,8,8 +.globl sigsetjmp +.type sigsetjmp, @function +sigsetjmp: + CFI_STARTPROC + // save env parameter + push %rdi + 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) + // align stack frame + sub $8, %rsp + CFI_ADJUST_CFA_OFFSET(8) + // obtain %rsp + lea 32(%rsp), %rdi + mov %rdi, %rsi + xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) + rol $0x11, %rsi + // call tsan interceptor + call __tsan_setjmp + // unalign stack frame + add $8, %rsp + CFI_ADJUST_CFA_OFFSET(-8) + // restore savesigs parameter + pop %rsi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rsi) + // restore env parameter + pop %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 +.size sigsetjmp, .-sigsetjmp + +.comm _ZN14__interception16real___sigsetjmpE,8,8 +.globl __sigsetjmp +.type __sigsetjmp, @function +__sigsetjmp: + CFI_STARTPROC + // save env parameter + push %rdi + 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) + // align stack frame + sub $8, %rsp + CFI_ADJUST_CFA_OFFSET(8) + // obtain %rsp + lea 32(%rsp), %rdi + mov %rdi, %rsi + xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) + rol $0x11, %rsi + // call tsan interceptor + call __tsan_setjmp + // unalign stack frame + add $8, %rsp + CFI_ADJUST_CFA_OFFSET(-8) + // restore savesigs parameter + pop %rsi + CFI_ADJUST_CFA_OFFSET(-8) + CFI_RESTORE(%rsi) + // restore env parameter + pop %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 +.size __sigsetjmp, .-__sigsetjmp #ifdef __linux__ /* We do not need executable stack. */ diff --git a/libsanitizer/tsan/tsan_stat.cc b/libsanitizer/tsan/tsan_stat.cc index cdd11ca22ae2..6bc345397adb 100644 --- a/libsanitizer/tsan/tsan_stat.cc +++ b/libsanitizer/tsan/tsan_stat.cc @@ -124,6 +124,7 @@ void StatOutput(u64 *stat) { name[StatInt_strlen] = " strlen "; name[StatInt_memset] = " memset "; name[StatInt_memcpy] = " memcpy "; + name[StatInt_textdomain] = " textdomain "; name[StatInt_strcmp] = " strcmp "; name[StatInt_memchr] = " memchr "; name[StatInt_memrchr] = " memrchr "; diff --git a/libsanitizer/tsan/tsan_stat.h b/libsanitizer/tsan/tsan_stat.h index 998f1cd5e2e8..3e08313d1a5f 100644 --- a/libsanitizer/tsan/tsan_stat.h +++ b/libsanitizer/tsan/tsan_stat.h @@ -121,6 +121,7 @@ enum StatType { StatInt_strlen, StatInt_memset, StatInt_memcpy, + StatInt_textdomain, StatInt_strcmp, StatInt_memchr, StatInt_memrchr, -- 2.43.5