Line data Source code
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_H_
6 : #define V8_TRAP_HANDLER_H_
7 :
8 : #include <signal.h>
9 : #include <stdint.h>
10 : #include <stdlib.h>
11 :
12 : #include "src/base/build_config.h"
13 : #include "src/flags.h"
14 : #include "src/globals.h"
15 :
16 : #if V8_OS_LINUX
17 : #include <ucontext.h>
18 : #endif
19 :
20 : namespace v8 {
21 : namespace internal {
22 : namespace trap_handler {
23 :
24 : // TODO(eholk): Support trap handlers on other platforms.
25 : #if V8_TARGET_ARCH_X64 && V8_OS_LINUX && !V8_OS_ANDROID
26 : #define V8_TRAP_HANDLER_SUPPORTED 1
27 : #else
28 : #define V8_TRAP_HANDLER_SUPPORTED 0
29 : #endif
30 :
31 : struct ProtectedInstructionData {
32 : // The offset of this instruction from the start of its code object.
33 : // Wasm code never grows larger than 2GB, so uint32_t is sufficient.
34 : uint32_t instr_offset;
35 :
36 : // The offset of the landing pad from the start of its code object.
37 : //
38 : // TODO(eholk): Using a single landing pad and store parameters here.
39 : uint32_t landing_offset;
40 : };
41 :
42 : const int kInvalidIndex = -1;
43 :
44 : /// Adjusts the base code pointer.
45 : void UpdateHandlerDataCodePointer(int index, void* base);
46 :
47 : /// Adds the handler data to the place where the signal handler will find it.
48 : ///
49 : /// This returns a number that can be used to identify the handler data to
50 : /// UpdateHandlerDataCodePointer and ReleaseHandlerData, or -1 on failure.
51 : int RegisterHandlerData(void* base, size_t size,
52 : size_t num_protected_instructions,
53 : ProtectedInstructionData* protected_instructions);
54 :
55 : /// Removes the data from the master list and frees any memory, if necessary.
56 : void ReleaseHandlerData(int index);
57 :
58 : #if V8_OS_WIN
59 : #define THREAD_LOCAL __declspec(thread)
60 : #elif V8_OS_ANDROID
61 : // TODO(eholk): fix this before enabling for trap handlers for Android.
62 : #define THREAD_LOCAL
63 : #else
64 : #define THREAD_LOCAL __thread
65 : #endif
66 :
67 10030 : inline bool UseTrapHandler() {
68 12143421 : return FLAG_wasm_trap_handler && V8_TRAP_HANDLER_SUPPORTED;
69 : }
70 :
71 : extern THREAD_LOCAL int g_thread_in_wasm_code;
72 :
73 2809932 : inline bool IsThreadInWasm() { return g_thread_in_wasm_code; }
74 :
75 : inline void SetThreadInWasm() {
76 5652972 : if (UseTrapHandler()) {
77 : DCHECK(!IsThreadInWasm());
78 5578213 : g_thread_in_wasm_code = true;
79 : }
80 : }
81 :
82 : inline void ClearThreadInWasm() {
83 5652792 : if (UseTrapHandler()) {
84 : DCHECK(IsThreadInWasm());
85 5578213 : g_thread_in_wasm_code = false;
86 : }
87 : }
88 :
89 : bool RegisterDefaultSignalHandler();
90 : V8_EXPORT_PRIVATE void RestoreOriginalSignalHandler();
91 :
92 : #if V8_OS_LINUX
93 : bool TryHandleSignal(int signum, siginfo_t* info, ucontext_t* context);
94 : #endif // V8_OS_LINUX
95 :
96 : size_t GetRecoveredTrapCount();
97 :
98 : } // namespace trap_handler
99 : } // namespace internal
100 : } // namespace v8
101 :
102 : #endif // V8_TRAP_HANDLER_H_
|