Support gcc build for aarch64.
[platform/framework/web/chromium-efl.git] / v8 / src / trap-handler / trap-handler.h
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"
14 #include "src/base/immediate-crash.h"
15
16 namespace v8 {
17 namespace internal {
18 namespace trap_handler {
19
20 // X64 on Linux, Windows, MacOS, FreeBSD.
21 #if V8_HOST_ARCH_X64 && V8_TARGET_ARCH_X64 &&                        \
22     ((V8_OS_LINUX && !V8_OS_ANDROID) || V8_OS_WIN || V8_OS_DARWIN || \
23      V8_OS_FREEBSD)
24 #define V8_TRAP_HANDLER_SUPPORTED true
25 // Arm64 (non-simulator) on Mac and Linux.
26 #elif V8_TARGET_ARCH_ARM64 && V8_HOST_ARCH_ARM64 && \
27     (V8_OS_DARWIN || (V8_OS_LINUX && !V8_OS_ANDROID)) && \
28     defined(__clang__)
29 #define V8_TRAP_HANDLER_SUPPORTED true
30 // Arm64 simulator on x64 on Linux, Mac, or Windows.
31 //
32 // The simulator case uses some inline assembly code, which cannot be
33 // compiled with MSVC, so don't enable the trap handler in that case.
34 // (MSVC #defines _MSC_VER, but so does Clang when targeting Windows, hence
35 // the check for __clang__.)
36 #elif V8_TARGET_ARCH_ARM64 && V8_HOST_ARCH_X64 && \
37     (V8_OS_LINUX || V8_OS_DARWIN || V8_OS_WIN) && \
38     (!defined(_MSC_VER) || defined(__clang__))
39 #define V8_TRAP_HANDLER_VIA_SIMULATOR
40 #define V8_TRAP_HANDLER_SUPPORTED true
41 // Loong64 (non-simulator) on Linux.
42 #elif V8_TARGET_ARCH_LOONG64 && V8_HOST_ARCH_LOONG64 && V8_OS_LINUX
43 #define V8_TRAP_HANDLER_SUPPORTED true
44 // Loong64 simulator on x64 on Linux
45 #elif V8_TARGET_ARCH_LOONG64 && V8_HOST_ARCH_X64 && V8_OS_LINUX
46 #define V8_TRAP_HANDLER_VIA_SIMULATOR
47 #define V8_TRAP_HANDLER_SUPPORTED true
48 // Everything else is unsupported.
49 #else
50 #define V8_TRAP_HANDLER_SUPPORTED false
51 #endif
52
53 #if V8_OS_ANDROID && V8_TRAP_HANDLER_SUPPORTED
54 // It would require some careful security review before the trap handler
55 // can be enabled on Android.  Android may do unexpected things with signal
56 // handling and crash reporting that could open up security holes in V8's
57 // trap handling.
58 #error "The V8 trap handler should not be enabled on Android"
59 #endif
60
61 // Setup for shared library export.
62 #if defined(BUILDING_V8_SHARED) && defined(V8_OS_WIN)
63 #define TH_EXPORT_PRIVATE __declspec(dllexport)
64 #elif defined(BUILDING_V8_SHARED)
65 #define TH_EXPORT_PRIVATE __attribute__((visibility("default")))
66 #elif defined(USING_V8_SHARED) && defined(V8_OS_WIN)
67 #define TH_EXPORT_PRIVATE __declspec(dllimport)
68 #else
69 #define TH_EXPORT_PRIVATE
70 #endif
71
72 #define TH_CHECK(condition) \
73   if (!(condition)) IMMEDIATE_CRASH();
74 #ifdef DEBUG
75 #define TH_DCHECK(condition) TH_CHECK(condition)
76 #else
77 #define TH_DCHECK(condition) void(0)
78 #endif
79
80 #if defined(__has_feature)
81 #if __has_feature(address_sanitizer)
82 #define TH_DISABLE_ASAN __attribute__((no_sanitize_address))
83 #else
84 #define TH_DISABLE_ASAN
85 #endif
86 #else
87 #define TH_DISABLE_ASAN
88 #endif
89
90 struct ProtectedInstructionData {
91   // The offset of this instruction from the start of its code object.
92   // Wasm code never grows larger than 2GB, so uint32_t is sufficient.
93   uint32_t instr_offset;
94 };
95
96 const int kInvalidIndex = -1;
97
98 /// Adds the handler data to the place where the trap handler will find it.
99 ///
100 /// This returns a number that can be used to identify the handler data to
101 /// ReleaseHandlerData, or -1 on failure.
102 int TH_EXPORT_PRIVATE RegisterHandlerData(
103     uintptr_t base, size_t size, size_t num_protected_instructions,
104     const ProtectedInstructionData* protected_instructions);
105
106 /// Removes the data from the master list and frees any memory, if necessary.
107 /// TODO(mtrofin): We can switch to using size_t for index and not need
108 /// kInvalidIndex.
109 void TH_EXPORT_PRIVATE ReleaseHandlerData(int index);
110
111 // Initially false, set to true if when trap handlers are enabled. Never goes
112 // back to false then.
113 TH_EXPORT_PRIVATE extern bool g_is_trap_handler_enabled;
114
115 // Initially true, set to false when either {IsTrapHandlerEnabled} or
116 // {EnableTrapHandler} is called to prevent calling {EnableTrapHandler}
117 // repeatedly, or after {IsTrapHandlerEnabled}. Needs to be atomic because
118 // {IsTrapHandlerEnabled} can be called from any thread. Updated using relaxed
119 // semantics, since it's not used for synchronization.
120 TH_EXPORT_PRIVATE extern std::atomic<bool> g_can_enable_trap_handler;
121
122 // Enables trap handling for WebAssembly bounds checks.
123 //
124 // use_v8_handler indicates that V8 should install its own handler
125 // rather than relying on the embedder to do it.
126 TH_EXPORT_PRIVATE bool EnableTrapHandler(bool use_v8_handler);
127
128 // Set the address that the trap handler should continue execution from when it
129 // gets a fault at a recognised address.
130 TH_EXPORT_PRIVATE void SetLandingPad(uintptr_t landing_pad);
131
132 inline bool IsTrapHandlerEnabled() {
133   TH_DCHECK(!g_is_trap_handler_enabled || V8_TRAP_HANDLER_SUPPORTED);
134   // Disallow enabling the trap handler after retrieving the current value.
135   // Re-enabling them late can produce issues because code or objects might have
136   // been generated under the assumption that trap handlers are disabled.
137   // Note: We test before setting to avoid contention by an unconditional write.
138   if (g_can_enable_trap_handler.load(std::memory_order_relaxed)) {
139     g_can_enable_trap_handler.store(false, std::memory_order_relaxed);
140   }
141   return g_is_trap_handler_enabled;
142 }
143
144 #if defined(V8_OS_AIX)
145 // `thread_local` does not link on AIX:
146 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100641
147 extern __thread int g_thread_in_wasm_code;
148 #else
149 extern thread_local int g_thread_in_wasm_code;
150 #endif
151
152 // Return the address of the thread-local {g_thread_in_wasm_code} variable. This
153 // pointer can be accessed and modified as long as the thread calling this
154 // function exists. Only use if from the same thread do avoid race conditions.
155 V8_NOINLINE TH_EXPORT_PRIVATE int* GetThreadInWasmThreadLocalAddress();
156
157 // On Windows, asan installs its own exception handler which maps shadow
158 // memory. Since our exception handler may be executed before the asan exception
159 // handler, we have to make sure that asan shadow memory is not accessed here.
160 TH_DISABLE_ASAN inline bool IsThreadInWasm() { return g_thread_in_wasm_code; }
161
162 inline void SetThreadInWasm() {
163   if (IsTrapHandlerEnabled()) {
164     TH_DCHECK(!IsThreadInWasm());
165     g_thread_in_wasm_code = true;
166   }
167 }
168
169 inline void ClearThreadInWasm() {
170   if (IsTrapHandlerEnabled()) {
171     TH_DCHECK(IsThreadInWasm());
172     g_thread_in_wasm_code = false;
173   }
174 }
175
176 bool RegisterDefaultTrapHandler();
177 TH_EXPORT_PRIVATE void RemoveTrapHandler();
178
179 TH_EXPORT_PRIVATE size_t GetRecoveredTrapCount();
180
181 }  // namespace trap_handler
182 }  // namespace internal
183 }  // namespace v8
184
185 #endif  // V8_TRAP_HANDLER_TRAP_HANDLER_H_