diff options
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_defs.h | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_mman.h | 1 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.cc | 20 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.h | 7 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_sync.cc | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_trace.h | 6 |
7 files changed, 42 insertions, 6 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_defs.h b/compiler-rt/lib/tsan/rtl/tsan_defs.h index 6406cdc5f2d..ca8f0aecc83 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_defs.h +++ b/compiler-rt/lib/tsan/rtl/tsan_defs.h @@ -28,9 +28,7 @@ const int kTidBits = 13; const unsigned kMaxTid = 1 << kTidBits; const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit. const int kClkBits = 43; -#ifdef TSAN_GO -const int kShadowStackSize = 8 * 1024; -#else +#ifndef TSAN_GO const int kShadowStackSize = 1024; #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_mman.h b/compiler-rt/lib/tsan/rtl/tsan_mman.h index b338a9c5343..53f147e40ce 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_mman.h +++ b/compiler-rt/lib/tsan/rtl/tsan_mman.h @@ -36,6 +36,7 @@ enum MBlockType { MBlockScopedBuf, MBlockString, MBlockStackTrace, + MBlockShadowStack, MBlockSync, MBlockClock, MBlockThreadContex, diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc index f27a5410fe3..81c3f727f84 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc @@ -451,14 +451,28 @@ void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size) { void FuncEntry(ThreadState *thr, uptr pc) { DCHECK_EQ(thr->in_rtl, 0); StatInc(thr, StatFuncEnter); - DPrintf2("#%d: tsan::FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc); + DPrintf2("#%d: FuncEntry %p\n", (int)thr->fast_state.tid(), (void*)pc); thr->fast_state.IncrementEpoch(); TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncEnter, pc); // Shadow stack maintenance can be replaced with // stack unwinding during trace switch (which presumably must be faster). DCHECK_GE(thr->shadow_stack_pos, &thr->shadow_stack[0]); +#ifndef TSAN_GO DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]); +#else + if (thr->shadow_stack_pos == thr->shadow_stack_end) { + const int sz = thr->shadow_stack_end - thr->shadow_stack; + const int newsz = 2 * sz; + uptr *newstack = (uptr*)internal_alloc(MBlockShadowStack, + newsz * sizeof(uptr)); + internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr)); + internal_free(thr->shadow_stack); + thr->shadow_stack = newstack; + thr->shadow_stack_pos = newstack + sz; + thr->shadow_stack_end = newstack + newsz; + } +#endif thr->shadow_stack_pos[0] = pc; thr->shadow_stack_pos++; } @@ -466,12 +480,14 @@ void FuncEntry(ThreadState *thr, uptr pc) { void FuncExit(ThreadState *thr) { DCHECK_EQ(thr->in_rtl, 0); StatInc(thr, StatFuncExit); - DPrintf2("#%d: tsan::FuncExit\n", (int)thr->fast_state.tid()); + DPrintf2("#%d: FuncExit\n", (int)thr->fast_state.tid()); thr->fast_state.IncrementEpoch(); TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeFuncExit, 0); DCHECK_GT(thr->shadow_stack_pos, &thr->shadow_stack[0]); +#ifndef TSAN_GO DCHECK_LT(thr->shadow_stack_pos, &thr->shadow_stack[kShadowStackSize]); +#endif thr->shadow_stack_pos--; } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 0d717d3a793..5cb95da1dd1 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -228,7 +228,14 @@ struct ThreadState { u64 *racy_shadow_addr; u64 racy_state[2]; Trace trace; +#ifndef TSAN_GO + // C/C++ uses embed shadow stack of fixed size. uptr shadow_stack[kShadowStackSize]; +#else + // Go uses satellite shadow stack with dynamic size. + uptr *shadow_stack; + uptr *shadow_stack_end; +#endif ThreadClock clock; u64 stat[StatCnt]; const int tid; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc index 81242a750c1..6756bd317ea 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc @@ -173,6 +173,14 @@ void ThreadStart(ThreadState *thr, int tid) { tctx->epoch1 = (u64)-1; new(thr) ThreadState(CTX(), tid, tctx->epoch0, stk_addr, stk_size, tls_addr, tls_size); +#ifdef TSAN_GO + // Setup dynamic shadow stack. + const int kInitStackSize = 8; + thr->shadow_stack = (uptr*)internal_alloc(MBlockShadowStack, + kInitStackSize * sizeof(uptr)); + thr->shadow_stack_pos = thr->shadow_stack; + thr->shadow_stack_end = thr->shadow_stack + kInitStackSize; +#endif tctx->thr = thr; thr->fast_synch_epoch = tctx->epoch0; thr->clock.set(tid, tctx->epoch0); diff --git a/compiler-rt/lib/tsan/rtl/tsan_sync.cc b/compiler-rt/lib/tsan/rtl/tsan_sync.cc index ebe7df4aaaf..2014121624b 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_sync.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_sync.cc @@ -174,7 +174,7 @@ void StackTrace::Init(const uptr *pcs, uptr cnt) { void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) { Reset(); - n_ = thr->shadow_stack_pos - &thr->shadow_stack[0]; + n_ = thr->shadow_stack_pos - thr->shadow_stack; if (n_ + !!toppc == 0) return; if (c_) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_trace.h b/compiler-rt/lib/tsan/rtl/tsan_trace.h index 1109d1d5814..a5853743f22 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_trace.h +++ b/compiler-rt/lib/tsan/rtl/tsan_trace.h @@ -42,10 +42,16 @@ typedef u64 Event; struct TraceHeader { StackTrace stack0; // Start stack for the trace. u64 epoch0; // Start epoch for the trace. +#ifndef TSAN_GO uptr stack0buf[kShadowStackSize]; +#endif TraceHeader() +#ifndef TSAN_GO : stack0(stack0buf, kShadowStackSize) +#else + : stack0() +#endif , epoch0() { } }; |

