node/deps/v8/src/common/code-memory-access-inl.h

110 lines
2.9 KiB
C++

// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMMON_CODE_MEMORY_ACCESS_INL_H_
#define V8_COMMON_CODE_MEMORY_ACCESS_INL_H_
#include "src/common/code-memory-access.h"
#include "src/flags/flags.h"
#if V8_HAS_PKU_JIT_WRITE_PROTECT
#include "src/base/platform/memory-protection-key.h"
#endif
namespace v8 {
namespace internal {
RwxMemoryWriteScope::RwxMemoryWriteScope(const char* comment) {
DCHECK(is_key_permissions_initialized_for_current_thread());
if (!v8_flags.jitless) {
SetWritable();
}
}
RwxMemoryWriteScope::~RwxMemoryWriteScope() {
if (!v8_flags.jitless) {
SetExecutable();
}
}
#if V8_HAS_PTHREAD_JIT_WRITE_PROTECT
// Ignoring this warning is considered better than relying on
// __builtin_available.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
// static
bool RwxMemoryWriteScope::IsSupported() { return true; }
// static
void RwxMemoryWriteScope::SetWritable() {
if (code_space_write_nesting_level_ == 0) {
pthread_jit_write_protect_np(0);
}
code_space_write_nesting_level_++;
}
// static
void RwxMemoryWriteScope::SetExecutable() {
code_space_write_nesting_level_--;
if (code_space_write_nesting_level_ == 0) {
pthread_jit_write_protect_np(1);
}
}
#pragma clang diagnostic pop
#elif V8_HAS_PKU_JIT_WRITE_PROTECT
// static
bool RwxMemoryWriteScope::IsSupported() {
static_assert(base::MemoryProtectionKey::kNoMemoryProtectionKey == -1);
DCHECK(pkey_initialized);
return memory_protection_key_ >= 0;
}
// static
void RwxMemoryWriteScope::SetWritable() {
DCHECK(pkey_initialized);
if (!IsSupported()) return;
if (code_space_write_nesting_level_ == 0) {
DCHECK_NE(
base::MemoryProtectionKey::GetKeyPermission(memory_protection_key_),
base::MemoryProtectionKey::kNoRestrictions);
base::MemoryProtectionKey::SetPermissionsForKey(
memory_protection_key_, base::MemoryProtectionKey::kNoRestrictions);
}
code_space_write_nesting_level_++;
}
// static
void RwxMemoryWriteScope::SetExecutable() {
DCHECK(pkey_initialized);
if (!IsSupported()) return;
code_space_write_nesting_level_--;
if (code_space_write_nesting_level_ == 0) {
DCHECK_EQ(
base::MemoryProtectionKey::GetKeyPermission(memory_protection_key_),
base::MemoryProtectionKey::kNoRestrictions);
base::MemoryProtectionKey::SetPermissionsForKey(
memory_protection_key_, base::MemoryProtectionKey::kDisableWrite);
}
}
#else // !V8_HAS_PTHREAD_JIT_WRITE_PROTECT && !V8_TRY_USE_PKU_JIT_WRITE_PROTECT
// static
bool RwxMemoryWriteScope::IsSupported() { return false; }
// static
void RwxMemoryWriteScope::SetWritable() {}
// static
void RwxMemoryWriteScope::SetExecutable() {}
#endif // V8_HAS_PTHREAD_JIT_WRITE_PROTECT
} // namespace internal
} // namespace v8
#endif // V8_COMMON_CODE_MEMORY_ACCESS_INL_H_