Commit c4c16f74 by Kostya Serebryany Committed by Kostya Serebryany

libsanitizer merge from upstream r196489

From-SVN: r205700
parent 022351a2
2013-12-05 Kostya Serebryany <kcc@google.com>
* All source files: Merge from upstream r196489.
* merge.sh: Add *.S to the list of merged files.
2013-12-05 Yury Gribov <y.gribov@samsung.com> 2013-12-05 Yury Gribov <y.gribov@samsung.com>
PR sanitizer/59368 PR sanitizer/59368
......
196090 196489
The first line of this file holds the svn revision number of the The first line of this file holds the svn revision number of the
last merge done from the master library sources. last merge done from the master library sources.
...@@ -63,8 +63,8 @@ static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; ...@@ -63,8 +63,8 @@ static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000;
#if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1
extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale; extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale;
extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset; extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset;
# define SHADOW_SCALE (__asan_mapping_scale) # define SHADOW_SCALE (__asan_mapping_scale)
# define SHADOW_OFFSET (__asan_mapping_offset) # define SHADOW_OFFSET (__asan_mapping_offset)
#else #else
......
...@@ -43,3 +43,11 @@ bool __asan_symbolize(const void *pc, char *out_buffer, int out_size) { ...@@ -43,3 +43,11 @@ bool __asan_symbolize(const void *pc, char *out_buffer, int out_size) {
return false; return false;
} }
#endif #endif
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_print_stack_trace() {
using namespace __asan;
PRINT_CURRENT_STACK();
}
} // extern "C"
...@@ -75,11 +75,10 @@ void PrintStack(const uptr *trace, uptr size); ...@@ -75,11 +75,10 @@ void PrintStack(const uptr *trace, uptr size);
#define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC #define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC
#define PRINT_CURRENT_STACK() \ #define PRINT_CURRENT_STACK() \
{ \ { \
GET_STACK_TRACE(kStackTraceMax, \ GET_STACK_TRACE_FATAL_HERE; \
common_flags()->fast_unwind_on_fatal); \ PrintStack(&stack); \
PrintStack(&stack); \
} }
#endif // ASAN_STACK_H #endif // ASAN_STACK_H
...@@ -83,6 +83,9 @@ extern "C" { ...@@ -83,6 +83,9 @@ extern "C" {
const void *old_mid, const void *old_mid,
const void *new_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 #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
......
...@@ -16,7 +16,7 @@ get_current_rev() { ...@@ -16,7 +16,7 @@ get_current_rev() {
} }
list_files() { list_files() {
(cd $1; ls *.{cc,h,inc} 2> /dev/null) (cd $1; ls *.{cc,h,inc,S} 2> /dev/null)
} }
......
...@@ -40,6 +40,13 @@ char report_path_prefix[sizeof(report_path_prefix)]; ...@@ -40,6 +40,13 @@ char report_path_prefix[sizeof(report_path_prefix)];
// child thread will be different from |report_fd_pid|. // child thread will be different from |report_fd_pid|.
uptr report_fd_pid = 0; 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; static DieCallbackType DieCallback;
void SetDieCallback(DieCallbackType callback) { void SetDieCallback(DieCallbackType callback) {
DieCallback = callback; DieCallback = callback;
......
...@@ -134,6 +134,8 @@ extern fd_t report_fd; ...@@ -134,6 +134,8 @@ extern fd_t report_fd;
extern bool log_to_file; extern bool log_to_file;
extern char report_path_prefix[4096]; extern char report_path_prefix[4096];
extern uptr report_fd_pid; extern uptr report_fd_pid;
extern uptr stoptheworld_tracer_pid;
extern uptr stoptheworld_tracer_ppid;
uptr OpenFile(const char *filename, bool write); uptr OpenFile(const char *filename, bool write);
// Opens the file 'file_name" and reads up to 'max_len' bytes. // Opens the file 'file_name" and reads up to 'max_len' bytes.
...@@ -318,8 +320,7 @@ template<typename T> ...@@ -318,8 +320,7 @@ template<typename T>
class InternalMmapVector { class InternalMmapVector {
public: public:
explicit InternalMmapVector(uptr initial_capacity) { explicit InternalMmapVector(uptr initial_capacity) {
CHECK_GT(initial_capacity, 0); capacity_ = Max(initial_capacity, (uptr)1);
capacity_ = initial_capacity;
size_ = 0; size_ = 0;
data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVector"); data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVector");
} }
......
...@@ -58,6 +58,22 @@ ...@@ -58,6 +58,22 @@
#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
#endif #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 #if SANITIZER_INTERCEPT_STRCMP
static inline int CharCmpX(unsigned char c1, unsigned char c2) { static inline int CharCmpX(unsigned char c1, unsigned char c2) {
return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
...@@ -2891,6 +2907,7 @@ INTERCEPTOR(__sanitizer_clock_t, times, void *tms) { ...@@ -2891,6 +2907,7 @@ INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
#endif #endif
#define SANITIZER_COMMON_INTERCEPTORS_INIT \ #define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_TEXTDOMAIN; \
INIT_STRCMP; \ INIT_STRCMP; \
INIT_STRNCMP; \ INIT_STRNCMP; \
INIT_STRCASECMP; \ INIT_STRCASECMP; \
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#endif #endif
# define SANITIZER_INTERCEPT_STRCMP 1 # define SANITIZER_INTERCEPT_STRCMP 1
# define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID
# define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS
......
...@@ -140,23 +140,32 @@ namespace __sanitizer { ...@@ -140,23 +140,32 @@ namespace __sanitizer {
int gid; int gid;
int cuid; int cuid;
int cgid; int cgid;
#ifdef __powerpc64__ #ifdef __powerpc__
unsigned mode; unsigned mode;
unsigned __seq; unsigned __seq;
u64 __unused1;
u64 __unused2;
#else #else
unsigned short mode; unsigned short mode;
unsigned short __pad1; unsigned short __pad1;
unsigned short __seq; unsigned short __seq;
unsigned short __pad2; unsigned short __pad2;
#if defined(__x86_64__) && !defined(_LP64)
u64 __unused1;
u64 __unused2;
#else
unsigned long __unused1;
unsigned long __unused2;
#endif
#endif #endif
uptr __unused1;
uptr __unused2;
}; };
struct __sanitizer_shmid_ds { struct __sanitizer_shmid_ds {
__sanitizer_ipc_perm shm_perm; __sanitizer_ipc_perm shm_perm;
#ifndef __powerpc__ #ifndef __powerpc__
uptr shm_segsz; uptr shm_segsz;
#elif !defined(__powerpc64__)
uptr __unused0;
#endif #endif
uptr shm_atime; uptr shm_atime;
#ifndef _LP64 #ifndef _LP64
...@@ -288,17 +297,20 @@ namespace __sanitizer { ...@@ -288,17 +297,20 @@ namespace __sanitizer {
typedef long __sanitizer_clock_t; typedef long __sanitizer_clock_t;
#if SANITIZER_LINUX #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_uid_t;
typedef unsigned __sanitizer___kernel_gid_t; typedef unsigned __sanitizer___kernel_gid_t;
typedef long long __sanitizer___kernel_off_t;
#else #else
typedef unsigned short __sanitizer___kernel_uid_t; typedef unsigned short __sanitizer___kernel_uid_t;
typedef unsigned short __sanitizer___kernel_gid_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; typedef long __sanitizer___kernel_off_t;
#endif #endif
#if defined(__powerpc64__) #if defined(__powerpc__)
typedef unsigned int __sanitizer___kernel_old_uid_t; typedef unsigned int __sanitizer___kernel_old_uid_t;
typedef unsigned int __sanitizer___kernel_old_gid_t; typedef unsigned int __sanitizer___kernel_old_gid_t;
#else #else
......
...@@ -196,10 +196,15 @@ char *FindPathToBinary(const char *name) { ...@@ -196,10 +196,15 @@ char *FindPathToBinary(const char *name) {
} }
void MaybeOpenReportFile() { 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<char> report_path_full(4096); InternalScopedBuffer<char> report_path_full(4096);
internal_snprintf(report_path_full.data(), report_path_full.size(), 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); uptr openrv = OpenFile(report_path_full.data(), true);
if (internal_iserror(openrv)) { if (internal_iserror(openrv)) {
report_fd = kStderrFd; report_fd = kStderrFd;
...@@ -212,7 +217,7 @@ void MaybeOpenReportFile() { ...@@ -212,7 +217,7 @@ void MaybeOpenReportFile() {
internal_close(report_fd); internal_close(report_fd);
} }
report_fd = openrv; report_fd = openrv;
report_fd_pid = internal_getpid(); report_fd_pid = pid;
} }
void RawWrite(const char *buffer) { void RawWrite(const char *buffer) {
...@@ -228,12 +233,11 @@ void RawWrite(const char *buffer) { ...@@ -228,12 +233,11 @@ void RawWrite(const char *buffer) {
bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) { bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
uptr s, e, off, prot; uptr s, e, off, prot;
InternalMmapVector<char> fn(4096); InternalScopedString buff(4096);
fn.push_back(0);
MemoryMappingLayout proc_maps(/*cache_enabled*/false); 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 if ((prot & MemoryMappingLayout::kProtectionExecute) != 0
&& internal_strcmp(module, &fn[0]) == 0) { && internal_strcmp(module, buff.data()) == 0) {
*start = s; *start = s;
*end = e; *end = e;
return true; return true;
......
...@@ -354,6 +354,20 @@ class StopTheWorldScope { ...@@ -354,6 +354,20 @@ class StopTheWorldScope {
int process_was_dumpable_; 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) { void StopTheWorld(StopTheWorldCallback callback, void *argument) {
StopTheWorldScope in_stoptheworld; StopTheWorldScope in_stoptheworld;
// Prepare the arguments for TracerThread. // Prepare the arguments for TracerThread.
...@@ -377,6 +391,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) { ...@@ -377,6 +391,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) {
Report("Failed spawning a tracer thread (errno %d).\n", local_errno); Report("Failed spawning a tracer thread (errno %d).\n", local_errno);
tracer_thread_argument.mutex.Unlock(); tracer_thread_argument.mutex.Unlock();
} else { } else {
ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid);
// On some systems we have to explicitly declare that we want to be traced // On some systems we have to explicitly declare that we want to be traced
// by the tracer thread. // by the tracer thread.
#ifdef PR_SET_PTRACER #ifdef PR_SET_PTRACER
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_internal.h" #include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_asm.h"
#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_libignore.h" #include "sanitizer_common/sanitizer_libignore.h"
#include "sanitizer_common/sanitizer_suppressions.h" #include "sanitizer_common/sanitizer_suppressions.h"
...@@ -734,11 +735,11 @@ void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c); ...@@ -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). // so we create a reserve stack frame for it (1024b must be enough).
#define HACKY_CALL(f) \ #define HACKY_CALL(f) \
__asm__ __volatile__("sub $1024, %%rsp;" \ __asm__ __volatile__("sub $1024, %%rsp;" \
".cfi_adjust_cfa_offset 1024;" \ CFI_INL_ADJUST_CFA_OFFSET(1024) \
".hidden " #f "_thunk;" \ ".hidden " #f "_thunk;" \
"call " #f "_thunk;" \ "call " #f "_thunk;" \
"add $1024, %%rsp;" \ "add $1024, %%rsp;" \
".cfi_adjust_cfa_offset -1024;" \ CFI_INL_ADJUST_CFA_OFFSET(-1024) \
::: "memory", "cc"); ::: "memory", "cc");
#else #else
#define HACKY_CALL(f) f() #define HACKY_CALL(f) f()
......
.section .text #include "sanitizer_common/sanitizer_asm.h"
.hidden __tsan_trace_switch
.globl __tsan_trace_switch_thunk .globl __tsan_trace_switch_thunk
__tsan_trace_switch_thunk: __tsan_trace_switch_thunk:
.cfi_startproc CFI_STARTPROC
# Save scratch registers. # Save scratch registers.
push %rax push %rax
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rax, 0 CFI_REL_OFFSET(%rax, 0)
push %rcx push %rcx
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rcx, 0 CFI_REL_OFFSET(%rcx, 0)
push %rdx push %rdx
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rdx, 0 CFI_REL_OFFSET(%rdx, 0)
push %rsi push %rsi
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rsi, 0 CFI_REL_OFFSET(%rsi, 0)
push %rdi push %rdi
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rdi, 0 CFI_REL_OFFSET(%rdi, 0)
push %r8 push %r8
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r8, 0 CFI_REL_OFFSET(%r8, 0)
push %r9 push %r9
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r9, 0 CFI_REL_OFFSET(%r9, 0)
push %r10 push %r10
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r10, 0 CFI_REL_OFFSET(%r10, 0)
push %r11 push %r11
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r11, 0 CFI_REL_OFFSET(%r11, 0)
# Align stack frame. # Align stack frame.
push %rbx # non-scratch push %rbx # non-scratch
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rbx, 0 CFI_REL_OFFSET(%rbx, 0)
mov %rsp, %rbx # save current rsp 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 shr $4, %rsp # clear 4 lsb, align to 16
shl $4, %rsp shl $4, %rsp
...@@ -44,78 +44,79 @@ __tsan_trace_switch_thunk: ...@@ -44,78 +44,79 @@ __tsan_trace_switch_thunk:
# Unalign stack frame back. # Unalign stack frame back.
mov %rbx, %rsp # restore the original rsp mov %rbx, %rsp # restore the original rsp
.cfi_def_cfa_register %rsp CFI_DEF_CFA_REGISTER(%rsp)
pop %rbx pop %rbx
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
# Restore scratch registers. # Restore scratch registers.
pop %r11 pop %r11
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %r10 pop %r10
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %r9 pop %r9
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %r8 pop %r8
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rdi pop %rdi
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rsi pop %rsi
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rdx pop %rdx
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rcx pop %rcx
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rax pop %rax
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
.cfi_restore %rax CFI_RESTORE(%rax)
.cfi_restore %rbx CFI_RESTORE(%rbx)
.cfi_restore %rcx CFI_RESTORE(%rcx)
.cfi_restore %rdx CFI_RESTORE(%rdx)
.cfi_restore %rsi CFI_RESTORE(%rsi)
.cfi_restore %rdi CFI_RESTORE(%rdi)
.cfi_restore %r8 CFI_RESTORE(%r8)
.cfi_restore %r9 CFI_RESTORE(%r9)
.cfi_restore %r10 CFI_RESTORE(%r10)
.cfi_restore %r11 CFI_RESTORE(%r11)
ret ret
.cfi_endproc CFI_ENDPROC
.hidden __tsan_report_race
.globl __tsan_report_race_thunk .globl __tsan_report_race_thunk
__tsan_report_race_thunk: __tsan_report_race_thunk:
.cfi_startproc CFI_STARTPROC
# Save scratch registers. # Save scratch registers.
push %rax push %rax
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rax, 0 CFI_REL_OFFSET(%rax, 0)
push %rcx push %rcx
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rcx, 0 CFI_REL_OFFSET(%rcx, 0)
push %rdx push %rdx
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rdx, 0 CFI_REL_OFFSET(%rdx, 0)
push %rsi push %rsi
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rsi, 0 CFI_REL_OFFSET(%rsi, 0)
push %rdi push %rdi
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rdi, 0 CFI_REL_OFFSET(%rdi, 0)
push %r8 push %r8
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r8, 0 CFI_REL_OFFSET(%r8, 0)
push %r9 push %r9
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r9, 0 CFI_REL_OFFSET(%r9, 0)
push %r10 push %r10
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r10, 0 CFI_REL_OFFSET(%r10, 0)
push %r11 push %r11
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %r11, 0 CFI_REL_OFFSET(%r11, 0)
# Align stack frame. # Align stack frame.
push %rbx # non-scratch push %rbx # non-scratch
.cfi_adjust_cfa_offset 8 CFI_ADJUST_CFA_OFFSET(8)
.cfi_rel_offset %rbx, 0 CFI_REL_OFFSET(%rbx, 0)
mov %rsp, %rbx # save current rsp 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 shr $4, %rsp # clear 4 lsb, align to 16
shl $4, %rsp shl $4, %rsp
...@@ -123,40 +124,177 @@ __tsan_report_race_thunk: ...@@ -123,40 +124,177 @@ __tsan_report_race_thunk:
# Unalign stack frame back. # Unalign stack frame back.
mov %rbx, %rsp # restore the original rsp mov %rbx, %rsp # restore the original rsp
.cfi_def_cfa_register %rsp CFI_DEF_CFA_REGISTER(%rsp)
pop %rbx pop %rbx
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
# Restore scratch registers. # Restore scratch registers.
pop %r11 pop %r11
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %r10 pop %r10
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %r9 pop %r9
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %r8 pop %r8
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rdi pop %rdi
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rsi pop %rsi
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rdx pop %rdx
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rcx pop %rcx
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
pop %rax pop %rax
.cfi_adjust_cfa_offset -8 CFI_ADJUST_CFA_OFFSET(-8)
.cfi_restore %rax CFI_RESTORE(%rax)
.cfi_restore %rbx CFI_RESTORE(%rbx)
.cfi_restore %rcx CFI_RESTORE(%rcx)
.cfi_restore %rdx CFI_RESTORE(%rdx)
.cfi_restore %rsi CFI_RESTORE(%rsi)
.cfi_restore %rdi CFI_RESTORE(%rdi)
.cfi_restore %r8 CFI_RESTORE(%r8)
.cfi_restore %r9 CFI_RESTORE(%r9)
.cfi_restore %r10 CFI_RESTORE(%r10)
.cfi_restore %r11 CFI_RESTORE(%r11)
ret 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__ #ifdef __linux__
/* We do not need executable stack. */ /* We do not need executable stack. */
......
...@@ -124,6 +124,7 @@ void StatOutput(u64 *stat) { ...@@ -124,6 +124,7 @@ void StatOutput(u64 *stat) {
name[StatInt_strlen] = " strlen "; name[StatInt_strlen] = " strlen ";
name[StatInt_memset] = " memset "; name[StatInt_memset] = " memset ";
name[StatInt_memcpy] = " memcpy "; name[StatInt_memcpy] = " memcpy ";
name[StatInt_textdomain] = " textdomain ";
name[StatInt_strcmp] = " strcmp "; name[StatInt_strcmp] = " strcmp ";
name[StatInt_memchr] = " memchr "; name[StatInt_memchr] = " memchr ";
name[StatInt_memrchr] = " memrchr "; name[StatInt_memrchr] = " memrchr ";
......
...@@ -121,6 +121,7 @@ enum StatType { ...@@ -121,6 +121,7 @@ enum StatType {
StatInt_strlen, StatInt_strlen,
StatInt_memset, StatInt_memset,
StatInt_memcpy, StatInt_memcpy,
StatInt_textdomain,
StatInt_strcmp, StatInt_strcmp,
StatInt_memchr, StatInt_memchr,
StatInt_memrchr, StatInt_memrchr,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment