1// Copyright 2021 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/wasm/code-space-access.h" 6 7#include "src/wasm/wasm-code-manager.h" 8#include "src/wasm/wasm-engine.h" 9 10namespace v8 { 11namespace internal { 12namespace wasm { 13 14thread_local NativeModule* CodeSpaceWriteScope::current_native_module_ = 15 nullptr; 16 17// TODO(jkummerow): Background threads could permanently stay in 18// writable mode; only the main thread has to switch back and forth. 19CodeSpaceWriteScope::CodeSpaceWriteScope(NativeModule* native_module) 20 : previous_native_module_(current_native_module_) { 21 DCHECK_NOT_NULL(native_module); 22 if (previous_native_module_ == native_module) return; 23 current_native_module_ = native_module; 24 if (previous_native_module_ == nullptr || SwitchingPerNativeModule()) { 25 SetWritable(); 26 } 27} 28 29CodeSpaceWriteScope::~CodeSpaceWriteScope() { 30 if (previous_native_module_ == current_native_module_) return; 31 if (previous_native_module_ == nullptr || SwitchingPerNativeModule()) { 32 SetExecutable(); 33 } 34 current_native_module_ = previous_native_module_; 35} 36 37#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT 38 39// Ignoring this warning is considered better than relying on 40// __builtin_available. 41#pragma clang diagnostic push 42#pragma clang diagnostic ignored "-Wunguarded-availability-new" 43// static 44void CodeSpaceWriteScope::SetWritable() { 45 pthread_jit_write_protect_np(0); 46} 47 48// static 49void CodeSpaceWriteScope::SetExecutable() { 50 pthread_jit_write_protect_np(1); 51} 52#pragma clang diagnostic pop 53 54// static 55bool CodeSpaceWriteScope::SwitchingPerNativeModule() { return false; } 56 57#else // !V8_HAS_PTHREAD_JIT_WRITE_PROTECT 58 59// static 60void CodeSpaceWriteScope::SetWritable() { 61 auto* code_manager = GetWasmCodeManager(); 62 if (code_manager->MemoryProtectionKeysEnabled()) { 63 code_manager->SetThreadWritable(true); 64 } else if (FLAG_wasm_write_protect_code_memory) { 65 current_native_module_->AddWriter(); 66 } 67} 68 69// static 70void CodeSpaceWriteScope::SetExecutable() { 71 auto* code_manager = GetWasmCodeManager(); 72 if (code_manager->MemoryProtectionKeysEnabled()) { 73 DCHECK(FLAG_wasm_memory_protection_keys); 74 code_manager->SetThreadWritable(false); 75 } else if (FLAG_wasm_write_protect_code_memory) { 76 current_native_module_->RemoveWriter(); 77 } 78} 79 80// static 81bool CodeSpaceWriteScope::SwitchingPerNativeModule() { 82 return !GetWasmCodeManager()->MemoryProtectionKeysEnabled() && 83 FLAG_wasm_write_protect_code_memory; 84} 85 86#endif // !V8_HAS_PTHREAD_JIT_WRITE_PROTECT 87 88} // namespace wasm 89} // namespace internal 90} // namespace v8 91