diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2012-07-16 16:44:47 +0000 | 
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2012-07-16 16:44:47 +0000 | 
| commit | 5bfac97ff9fce86ad3d723455f85f9f3c09cc15c (patch) | |
| tree | bfc336bfa62a34fb613768555c2f2a37bba01c35 /compiler-rt | |
| parent | 6c7dbf5858726d7ed5a2c1bc7143cc2792cbd820 (diff) | |
| download | bcm5719-llvm-5bfac97ff9fce86ad3d723455f85f9f3c09cc15c.tar.gz bcm5719-llvm-5bfac97ff9fce86ad3d723455f85f9f3c09cc15c.zip | |
tsan: use dynamic shadow stack for Go
llvm-svn: 160288
Diffstat (limited to 'compiler-rt')
| -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() {    }  }; | 

