v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
trap-handler.h
Go to the documentation of this file.
1// Copyright 2016 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#ifndef V8_TRAP_HANDLER_TRAP_HANDLER_H_
6#define V8_TRAP_HANDLER_TRAP_HANDLER_H_
7
8#include <stdint.h>
9#include <stdlib.h>
10
11#include <atomic>
12
13#include "include/v8config.h"
15
17
18// X64 on Linux, Windows, MacOS, FreeBSD.
19#if V8_HOST_ARCH_X64 && V8_TARGET_ARCH_X64 && \
20 ((V8_OS_LINUX && !V8_OS_ANDROID) || V8_OS_WIN || V8_OS_DARWIN || \
21 V8_OS_FREEBSD)
22#define V8_TRAP_HANDLER_SUPPORTED true
23// Arm64 (non-simulator) on Linux, Windows, MacOS.
24#elif V8_TARGET_ARCH_ARM64 && V8_HOST_ARCH_ARM64 && \
25 ((V8_OS_LINUX && !V8_OS_ANDROID) || V8_OS_WIN || V8_OS_DARWIN)
26#define V8_TRAP_HANDLER_SUPPORTED true
27// Arm64 simulator on x64 on Linux, Mac, or Windows.
28//
29// The simulator case uses some inline assembly code, which cannot be
30// compiled with MSVC, so don't enable the trap handler in that case.
31// (MSVC #defines _MSC_VER, but so does Clang when targeting Windows, hence
32// the check for __clang__.)
33#elif V8_TARGET_ARCH_ARM64 && V8_HOST_ARCH_X64 && \
34 (V8_OS_LINUX || V8_OS_DARWIN || V8_OS_WIN) && \
35 (!defined(_MSC_VER) || defined(__clang__))
36#define V8_TRAP_HANDLER_VIA_SIMULATOR
37#define V8_TRAP_HANDLER_SUPPORTED true
38// Loong64 (non-simulator) on Linux.
39#elif V8_TARGET_ARCH_LOONG64 && V8_HOST_ARCH_LOONG64 && V8_OS_LINUX
40#define V8_TRAP_HANDLER_SUPPORTED true
41// Loong64 simulator on x64 on Linux
42#elif V8_TARGET_ARCH_LOONG64 && V8_HOST_ARCH_X64 && V8_OS_LINUX
43#define V8_TRAP_HANDLER_VIA_SIMULATOR
44#define V8_TRAP_HANDLER_SUPPORTED true
45// RISCV64 (non-simulator) on Linux.
46#elif V8_TARGET_ARCH_RISCV64 && V8_HOST_ARCH_RISCV64 && V8_OS_LINUX && \
47 !V8_OS_ANDROID
48#define V8_TRAP_HANDLER_SUPPORTED true
49// RISCV64 simulator on x64 on Linux
50#elif V8_TARGET_ARCH_RISCV64 && V8_HOST_ARCH_X64 && V8_OS_LINUX
51#define V8_TRAP_HANDLER_VIA_SIMULATOR
52#define V8_TRAP_HANDLER_SUPPORTED true
53// Everything else is unsupported.
54#else
55#define V8_TRAP_HANDLER_SUPPORTED false
56#endif
57
58#if V8_OS_ANDROID && V8_TRAP_HANDLER_SUPPORTED
59// It would require some careful security review before the trap handler
60// can be enabled on Android. Android may do unexpected things with signal
61// handling and crash reporting that could open up security holes in V8's
62// trap handling.
63#error "The V8 trap handler should not be enabled on Android"
64#endif
65
66// Setup for shared library export.
67#ifdef V8_OS_WIN
68
69#if defined(BUILDING_V8_SHARED_PRIVATE)
70#define TH_EXPORT_PRIVATE __declspec(dllexport)
71#elif defined(USING_V8_SHARED_PRIVATE)
72#define TH_EXPORT_PRIVATE __declspec(dllimport)
73#else
74#define TH_EXPORT_PRIVATE __attribute__((visibility("default")))
75#endif // BUILDING_V8_SHARED_PRIVATE
76
77#else // V8_OS_WIN
78
79#if defined(BUILDING_V8_SHARED_PRIVATE) || defined(USING_V8_SHARED_PRIVATE)
80#define TH_EXPORT_PRIVATE __attribute__((visibility("default")))
81#else
82#define TH_EXPORT_PRIVATE
83#endif // BUILDING_V8_SHARED_PRIVATE ||
84
85#endif // V8_OS_WIN
86
87#define TH_CHECK(condition) \
88 if (!(condition)) IMMEDIATE_CRASH();
89#ifdef DEBUG
90#define TH_DCHECK(condition) TH_CHECK(condition)
91#else
92#define TH_DCHECK(condition) void(0)
93#endif
94
95#if defined(__has_feature)
96#if __has_feature(address_sanitizer)
97#define TH_DISABLE_ASAN __attribute__((no_sanitize_address))
98#else
99#define TH_DISABLE_ASAN
100#endif
101#else
102#define TH_DISABLE_ASAN
103#endif
104
106 // The offset of this instruction from the start of its code object.
107 // Wasm code never grows larger than 2GB, so uint32_t is sufficient.
108 uint32_t instr_offset;
109};
110
111const int kInvalidIndex = -1;
112
118 uintptr_t base, size_t size, size_t num_protected_instructions,
119 const ProtectedInstructionData* protected_instructions);
120
125
131bool TH_EXPORT_PRIVATE RegisterV8Sandbox(uintptr_t base, size_t size);
132
135void TH_EXPORT_PRIVATE UnregisterV8Sandbox(uintptr_t base, size_t size);
136
137// Initially false, set to true if when trap handlers are enabled. Never goes
138// back to false then.
140
141// Initially true, set to false when either {IsTrapHandlerEnabled} or
142// {EnableTrapHandler} is called to prevent calling {EnableTrapHandler}
143// repeatedly, or after {IsTrapHandlerEnabled}. Needs to be atomic because
144// {IsTrapHandlerEnabled} can be called from any thread. Updated using relaxed
145// semantics, since it's not used for synchronization.
146TH_EXPORT_PRIVATE extern std::atomic<bool> g_can_enable_trap_handler;
147
148// Enables trap handling for WebAssembly bounds checks.
149//
150// use_v8_handler indicates that V8 should install its own handler
151// rather than relying on the embedder to do it.
152TH_EXPORT_PRIVATE bool EnableTrapHandler(bool use_v8_handler);
153
154// Set the address that the trap handler should continue execution from when it
155// gets a fault at a recognised address.
156TH_EXPORT_PRIVATE void SetLandingPad(uintptr_t landing_pad);
157
158inline bool IsTrapHandlerEnabled() {
160 // Disallow enabling the trap handler after retrieving the current value.
161 // Re-enabling them late can produce issues because code or objects might have
162 // been generated under the assumption that trap handlers are disabled.
163 // Note: We test before setting to avoid contention by an unconditional write.
164 if (g_can_enable_trap_handler.load(std::memory_order_relaxed)) {
165 g_can_enable_trap_handler.store(false, std::memory_order_relaxed);
166 }
168}
169
170#if defined(V8_OS_AIX)
171// `thread_local` does not link on AIX:
172// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100641
173extern __thread int g_thread_in_wasm_code;
174#else
175extern thread_local int g_thread_in_wasm_code;
176#endif
177
178// Return the address of the thread-local {g_thread_in_wasm_code} variable. This
179// pointer can be accessed and modified as long as the thread calling this
180// function exists. Only use if from the same thread do avoid race conditions.
182
183// On Windows, asan installs its own exception handler which maps shadow
184// memory. Since our exception handler may be executed before the asan exception
185// handler, we have to make sure that asan shadow memory is not accessed here.
187
188inline void SetThreadInWasm() {
189 if (IsTrapHandlerEnabled()) {
192 }
193}
194
195inline void ClearThreadInWasm() {
196 if (IsTrapHandlerEnabled()) {
198 g_thread_in_wasm_code = false;
199 }
200}
201
204
206
207// Check that the current thread does not have the "in wasm" flag set, without
208// any other side effects. Note that e.g. "!IsTrapHandlerEnabled() ||
209// !IsThreadInWasm()" has the side effect of disabling later
210// EnableTrapHandler(). We need to allow later enabling though, because
211// allocations can happen *before* initializing the trap handler, and we want to
212// execute this check there.
213#if defined(BUILDING_V8_SHARED_PRIVATE) || defined(USING_V8_SHARED_PRIVATE)
215#else
219#endif
220
221} // namespace v8::internal::trap_handler
222
223#endif // V8_TRAP_HANDLER_TRAP_HANDLER_H_
std::atomic< bool > g_can_enable_trap_handler
thread_local int g_thread_in_wasm_code
void SetLandingPad(uintptr_t landing_pad)
int RegisterHandlerData(uintptr_t base, size_t size, size_t num_protected_instructions, const ProtectedInstructionData *protected_instructions)
bool EnableTrapHandler(bool use_v8_handler)
TH_DISABLE_ASAN bool IsThreadInWasm()
void UnregisterV8Sandbox(uintptr_t base, size_t size)
bool RegisterV8Sandbox(uintptr_t base, size_t size)
#define TH_EXPORT_PRIVATE
#define V8_TRAP_HANDLER_SUPPORTED
#define TH_DCHECK(condition)
#define TH_DISABLE_ASAN
#define V8_NOINLINE
Definition v8config.h:586