diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc index e02f2af1d85..c59b714a90c 100644 --- a/runtime/vm/dart_entry.cc +++ b/runtime/vm/dart_entry.cc @@ -52,8 +52,11 @@ class DartEntryScope : public TransitionToGenerated { #if defined(USING_SAFE_STACK) // Remember the safestack pointer at entry so it can be restored in // Exceptions::JumpToFrame when a Dart exception jumps over C++ frames. - saved_safestack_limit_ = OSThread::GetCurrentSafestackPointer(); - thread->set_saved_safestack_limit(saved_safestack_limit_); + saved_safestack_ = thread->saved_safestack(); + thread->set_saved_safestack(OSThread::GetCurrentSafestackPointer()); +#endif +#if defined(USING_SHADOW_CALL_STACK) + saved_shadow_call_stack_ = thread->saved_shadow_call_stack(); #endif saved_api_scope_ = thread->api_top_scope(); @@ -67,8 +70,11 @@ class DartEntryScope : public TransitionToGenerated { thread()->ExitApiScope(); } +#if defined(USING_SHADOW_CALL_STACK) + thread()->set_saved_shadow_call_stack(saved_shadow_call_stack_); +#endif #if defined(USING_SAFE_STACK) - thread()->set_saved_safestack_limit(saved_safestack_limit_); + thread()->set_saved_safestack(saved_safestack_); #endif ASSERT(thread()->long_jump_base() == nullptr); @@ -78,7 +84,10 @@ class DartEntryScope : public TransitionToGenerated { private: LongJumpScope* saved_long_jump_base_; #if defined(USING_SAFE_STACK) - uword saved_safestack_limit_ = 0; + uword saved_safestack_ = 0; +#endif +#if defined(USING_SHADOW_CALL_STACK) + uword saved_shadow_call_stack_ = 0; #endif ApiLocalScope* saved_api_scope_; }; diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc index b1010480179..3e36df06a60 100644 --- a/runtime/vm/exceptions.cc +++ b/runtime/vm/exceptions.cc @@ -650,7 +650,7 @@ NO_SANITIZE_SAFE_STACK // This function manipulates the safestack pointer. // We are jumping over C++ frames, so we have to set the safestack pointer // back to what it was when we entered the runtime from Dart code. #if defined(USING_SAFE_STACK) - const uword saved_ssp = thread->saved_safestack_limit(); + const uword saved_ssp = thread->saved_safestack(); OSThread::SetCurrentSafestackPointer(saved_ssp); #endif diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc index a1ff5226490..8b6c962a74c 100644 --- a/runtime/vm/os_thread_fuchsia.cc +++ b/runtime/vm/os_thread_fuchsia.cc @@ -153,7 +153,7 @@ void OSThread::Join(ThreadJoinId id) { } void OSThread::Detach(ThreadJoinId id) { - int result = pthread_detach(id); + int result = pthread_detach(id); // NOLINT VALIDATE_PTHREAD_RESULT(result); } @@ -202,6 +202,10 @@ uword OSThread::GetCurrentSafestackPointer() { asm volatile("mrs %0, TPIDR_EL0;\n" _loadword(ZX_TLS_UNSAFE_SP_OFFSET) : "=r"(result) // outputs ); +#elif defined(HOST_ARCH_RISCV64) + asm volatile("ld %0, " STRINGIFY(ZX_TLS_UNSAFE_SP_OFFSET) "(tp)" + : "=r"(result) // outputs + ); #else #error "Architecture not supported" #endif @@ -229,6 +233,12 @@ void OSThread::SetCurrentSafestackPointer(uword ssp) { : "r"(ssp) // inputs. : // clobbered. ); +#elif defined(HOST_ARCH_RISCV64) + asm volatile("sd %0, " STRINGIFY(ZX_TLS_UNSAFE_SP_OFFSET) "(tp)" + : // outputs. + : "r"(ssp) // inputs. + : // clobbered. + ); #else #error "Architecture not supported" #endif diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index e10c2c5dac0..2e25f3a42ac 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h @@ -425,9 +425,9 @@ class Thread : public ThreadState, public IntrusiveDListEntry { void SetStackLimit(uword value); void ClearStackLimit(); - // Access to the current stack limit for generated code. Either the true OS - // thread's stack limit minus some headroom, or a special value to trigger - // interrupts. + // The stack limit used by stack overflow checks in generated code. Either the + // true OS thread's stack limit minus some headroom, or a special value to + // trigger interrupts. uword stack_limit_address() const { return reinterpret_cast(&stack_limit_); } @@ -435,19 +435,27 @@ class Thread : public ThreadState, public IntrusiveDListEntry { return OFFSET_OF(Thread, stack_limit_); } - // The true stack limit for this OS thread. + // The true stack limit for this OS thread minus some headroom. Used on ARM64 + // to keep CSP/R31 signal-handler safe while Dart uses R15 as its stack + // pointer. static intptr_t saved_stack_limit_offset() { return OFFSET_OF(Thread, saved_stack_limit_); } uword saved_stack_limit() const { return saved_stack_limit_; } #if defined(USING_SAFE_STACK) - uword saved_safestack_limit() const { return saved_safestack_limit_; } - void set_saved_safestack_limit(uword limit) { - saved_safestack_limit_ = limit; - } + // The SafeStack pointer during the top-most DartEntry. Needs to be restored + // on Dart throw like longjmp would. + uword saved_safestack() const { return saved_safestack_; } + void set_saved_safestack(uword ssp) { saved_safestack_ = ssp; } #endif + + // The ShadowCallStack pointer during the top-most entry frame. Needs to be + // restored on Dart throw like longjmp would. uword saved_shadow_call_stack() const { return saved_shadow_call_stack_; } + void set_saved_shadow_call_stack(uword ssp) { + saved_shadow_call_stack_ = ssp; + } static uword saved_shadow_call_stack_offset() { return OFFSET_OF(Thread, saved_shadow_call_stack_); } @@ -1634,7 +1642,7 @@ class Thread : public ThreadState, public IntrusiveDListEntry { } #if defined(USING_SAFE_STACK) - uword saved_safestack_limit_ = 0; + uword saved_safestack_ = 0; #endif Thread* next_; // Used to chain the thread structures in an isolate.